home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume11 / ephem4.12 / part03 < prev    next >
Encoding:
Text File  |  1990-03-10  |  59.6 KB  |  2,161 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v11i004: ephem, 3 of 7
  3. From: ecd@cs.umn.edu@ncs-med.UUCP (Elwood C. Downey)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 11, Issue 4
  7. Submitted-by: ecd@cs.umn.edu@ncs-med.UUCP (Elwood C. Downey)
  8. Archive-name: ephem4.12/part03
  9.  
  10. # This is the first line of a "shell archive" file.
  11. # This means it contains several files that can be extracted into
  12. # the current directory when run with the sh shell, as follows:
  13. #    sh < this_file_name
  14. # This is file 3.
  15. echo x mainmenu.c
  16. sed -e 's/^X//' << 'EOFxEOF' > mainmenu.c
  17. X/* printing routines for the main (upper) screen.
  18. X */
  19. X
  20. X#include <stdio.h>
  21. X#include <math.h>
  22. X#include "astro.h"
  23. X#include "circum.h"
  24. X#include "screen.h"
  25. X
  26. X/* #define PC_GRAPHICS */
  27. X#ifdef PC_GRAPHICS
  28. X#define    JOINT    207
  29. X#define    VERT    179
  30. X#define    HORIZ    205
  31. X#else
  32. X#define    JOINT    '-'
  33. X#define    VERT    '|'
  34. X#define    HORIZ    '-'
  35. X#endif
  36. X
  37. Xmm_borders()
  38. X{
  39. X    char line[NC+1], *lp;
  40. X    register i;
  41. X
  42. X    lp = line;
  43. X    for (i = 0; i < NC; i++)
  44. X        *lp++ = HORIZ;
  45. X    *lp = '\0';
  46. X    f_string (R_PLANTAB-1, 1, line);
  47. X    for (i = R_TOP; i < R_PLANTAB-1; i++)
  48. X        f_char (i, COL2-2, VERT);
  49. X    f_char (R_PLANTAB-1, COL2-2, JOINT);
  50. X    for (i = R_TOP; i < R_PLANTAB-1; i++)
  51. X        f_char (i, COL3-2, VERT);
  52. X    f_char (R_PLANTAB-1, COL3-2, JOINT);
  53. X    for (i = R_LST; i < R_PLANTAB-1; i++)
  54. X        f_char (i, COL4-2, VERT);
  55. X    f_char (R_PLANTAB-1, COL4-2, JOINT);
  56. X}
  57. X
  58. X/* print the permanent labels, on the top menu and the planet names
  59. X * in the bottom section.
  60. X */
  61. Xmm_labels()
  62. X{
  63. X    f_string (R_TZN,    C_TZN,        "LT");
  64. X    f_string (R_UT,        C_UT,        "UTC");
  65. X    f_string (R_JD,        C_JD,        "JulianDate");
  66. X    f_string (R_WATCH,    C_WATCH,    "Watch");
  67. X    f_string (R_SRCH,    C_SRCH,        "Search");
  68. X    f_string (R_PLOT,    C_PLOT,        "Plot");
  69. X    f_string (R_ALTM,    C_ALTM,        "Menu");
  70. X
  71. X    f_string (R_LST,    C_LST,        "LST");
  72. X    f_string (R_DAWN,    C_DAWN,        "Dawn");
  73. X    f_string (R_DUSK,    C_DUSK,        "Dusk");
  74. X    f_string (R_LON,    C_LON,        "NiteLn");
  75. X    f_string (R_NSTEP,    C_NSTEP,    "NStep");
  76. X    f_string (R_STPSZ,    C_STPSZ,    "StpSz");
  77. X
  78. X    f_string (R_LAT,    C_LAT,        "Lat");
  79. X    f_string (R_LONG,    C_LONG,        "Long");
  80. X    f_string (R_HEIGHT,    C_HEIGHT,    "Elev");
  81. X    f_string (R_TEMP,    C_TEMP,        "Temp");
  82. X    f_string (R_PRES,    C_PRES,        "AtmPr");
  83. X    f_string (R_TZONE,    C_TZONE,    "TZ");
  84. X    f_string (R_EPOCH,    C_EPOCH,    "Epoch");
  85. X
  86. X    f_string (R_PLANTAB,    C_OBJ,    "Ob");
  87. X    f_string (R_SUN,    C_OBJ,    "Su");
  88. X    f_string (R_MOON,    C_OBJ,    "Mo");
  89. X    f_string (R_MERCURY,    C_OBJ,    "Me");
  90. X    f_string (R_VENUS,    C_OBJ,    "Ve");
  91. X    f_string (R_MARS,    C_OBJ,    "Ma");
  92. X    f_string (R_JUPITER,    C_OBJ,    "Ju");
  93. X    f_string (R_SATURN,    C_OBJ,    "Sa");
  94. X    f_string (R_URANUS,    C_OBJ,    "Ur");
  95. X    f_string (R_NEPTUNE,    C_OBJ,    "Ne");
  96. X    f_string (R_PLUTO,    C_OBJ,    "Pl");
  97. X    f_string (R_OBJX,    C_OBJ,    "X");
  98. X}
  99. X
  100. X/* print all the time/date/where related stuff: the Now structure.
  101. X * print in a nice order, based on the field locations, as much as possible.
  102. X */
  103. Xmm_now (np, all)
  104. XNow *np;
  105. Xint all;
  106. X{
  107. X    char buf[32];
  108. X    double lmjd = mjd - tz/24.0;
  109. X    double jd = mjd + 2415020L;
  110. X    double tmp;
  111. X
  112. X    sprintf (buf, "%-3.3s", tznm);
  113. X    f_string (R_TZN, C_TZN, buf);
  114. X    f_time (R_LT, C_LT, mjd_hr(lmjd));
  115. X    f_date (R_LD, C_LD, mjd_day(lmjd));
  116. X
  117. X    f_time (R_UT, C_UTV, mjd_hr(mjd));
  118. X    f_date (R_UD, C_UD, mjd_day(mjd));
  119. X
  120. X    sprintf (buf, "%14.5f", jd);
  121. X    (void) flog_log (R_JD, C_JDV, jd);
  122. X    f_string (R_JD, C_JDV, buf);
  123. X
  124. X    now_lst (np, &tmp);
  125. X    f_time (R_LST, C_LSTV, tmp);
  126. X
  127. X    if (all) {
  128. X        f_gangle (R_LAT, C_LATV, lat);
  129. X        f_gangle (R_LONG, C_LONGV, -lng);    /* + west */
  130. X
  131. X        tmp = height * 2.093e7;    /* want to see ft, not earth radii */
  132. X        sprintf (buf, "%5g ft", tmp);
  133. X        (void) flog_log (R_HEIGHT, C_HEIGHTV, tmp);
  134. X        f_string (R_HEIGHT, C_HEIGHTV, buf);
  135. X
  136. X        tmp = 9./5.*temp + 32.0;     /* want to see degrees F, not C */
  137. X        (void) flog_log (R_TEMP, C_TEMPV, tmp);
  138. X        sprintf (buf, "%6g F", tmp);
  139. X        f_string (R_TEMP, C_TEMPV, buf);
  140. X
  141. X        tmp = pressure / 33.86;    /* want to see in. Hg, not mBar */
  142. X        (void) flog_log (R_PRES, C_PRESV, tmp);
  143. X        sprintf (buf, "%5.2f in", tmp);
  144. X        f_string (R_PRES, C_PRESV, buf);
  145. X
  146. X        f_signtime (R_TZONE, C_TZONEV, tz);
  147. X
  148. X        if (epoch == EOD)
  149. X        f_string (R_EPOCH, C_EPOCHV, "(OfDate)");
  150. X        else {
  151. X        mjd_year (epoch, &tmp);
  152. X        f_double (R_EPOCH, C_EPOCHV, "%8.1f", tmp);
  153. X        }
  154. X    }
  155. X
  156. X    /* print the calendar for local day, if new month/year.  */
  157. X    mm_calendar (np, all > 1);
  158. X}
  159. X
  160. X/* display dawn/dusk/length-of-night times.
  161. X */
  162. Xmm_twilight (np, force)
  163. XNow *np;
  164. Xint force;
  165. X{
  166. X    double dusk, dawn;
  167. X    double tmp;
  168. X    int status;
  169. X
  170. X    if (!twilight_cir (np, &dawn, &dusk, &status) && !force)
  171. X        return;
  172. X
  173. X    if (status != 0) {
  174. X        f_blanks (R_DAWN, C_DAWNV, 5);
  175. X        f_blanks (R_DUSK, C_DUSKV, 5);
  176. X        f_string (R_LON, C_LONV, "-----");
  177. X        return;
  178. X    }
  179. X
  180. X    f_mtime (R_DAWN, C_DAWNV, dawn);
  181. X    f_mtime (R_DUSK, C_DUSKV, dusk);
  182. X    tmp = dawn - dusk; range (&tmp, 24.0);
  183. X    f_mtime (R_LON, C_LONV, tmp);
  184. X}
  185. X
  186. Xmm_newcir (y)
  187. Xint y;
  188. X{
  189. X    static char ncmsg[] = "NEW CIRCUMSTANCES";
  190. X    static char nomsg[] = "                 ";
  191. X    static int last_y = -1;
  192. X
  193. X    if (y != last_y) {
  194. X        f_string (R_NEWCIR, C_NEWCIR, y ? ncmsg : nomsg);
  195. X        last_y = y;
  196. X    }
  197. X}
  198. X
  199. Xstatic
  200. Xmm_calendar (np, force)
  201. XNow *np;
  202. Xint force;
  203. X{
  204. X    static char *mnames[] = {
  205. X        "January", "February", "March", "April", "May", "June",
  206. X        "July", "August", "September", "October", "November", "December"
  207. X    };
  208. X    static int last_m, last_y;
  209. X    static double last_tz;
  210. X    char str[64];
  211. X    int m, y;
  212. X    double d;
  213. X    int f, nd;
  214. X    int r;
  215. X    double jd0;
  216. X
  217. X    /* get local m/d/y. do nothing if still same month and not forced. */
  218. X    mjd_cal (mjd_day(mjd-tz/24.0), &m, &d, &y);
  219. X    if (m == last_m && y == last_y && tz == last_tz && !force)
  220. X        return;
  221. X    last_m = m;
  222. X    last_y = y;
  223. X    last_tz = tz;
  224. X
  225. X    /* find day of week of first day of month */
  226. X    cal_mjd (m, 1.0, y, &jd0);
  227. X    mjd_dow (jd0, &f);
  228. X    if (f < 0) {
  229. X        /* can't figure it out - too hard before Gregorian */
  230. X        int i;
  231. X        for (i = 8; --i >= 0; )
  232. X        f_string (R_CAL+i, C_CAL, "                    ");
  233. X        return;
  234. X    }
  235. X
  236. X    /* print header */
  237. X    f_blanks (R_CAL, C_CAL, 20);
  238. X    sprintf (str, "%s %4d", mnames[m-1], y);
  239. X    f_string (R_CAL, C_CAL + (20 - (strlen(mnames[m-1]) + 5))/2, str);
  240. X    f_string (R_CAL+1, C_CAL, "Su Mo Tu We Th Fr Sa");
  241. X
  242. X    /* find number of days in this month */
  243. X    mjd_dpm (jd0, &nd);
  244. X
  245. X    /* print the calendar */
  246. X    for (r = 0; r < 6; r++) {
  247. X        char row[7*3+1], *rp = row;
  248. X        int c;
  249. X        for (c = 0; c < 7; c++) {
  250. X        int i = r*7+c;
  251. X        if (i < f || i >= f + nd)
  252. X            sprintf (rp, "   ");
  253. X        else
  254. X            sprintf (rp, "%2d ", i-f+1);
  255. X        rp += 3;
  256. X        }
  257. X        row[sizeof(row)-2] = '\0';    /* don't print last blank; causes wrap*/
  258. X        f_string (R_CAL+2+r, C_CAL, row);
  259. X    }
  260. X
  261. X    /* over print the new and full moons for this month.
  262. X     * TODO: don't really know which dates to use here (see moonnf())
  263. X     *   so try several to be fairly safe. have to go back to 4/29/1988
  264. X     *   to find the full moon on 5/1 for example.
  265. X     */
  266. X    mm_nfmoon (jd0-3, tz, m, f);
  267. X    mm_nfmoon (jd0+15, tz, m, f);
  268. X}
  269. X
  270. Xstatic
  271. Xmm_nfmoon (jd, tzone, m, f)
  272. Xdouble jd, tzone;
  273. Xint m, f;
  274. X{
  275. X    static char nm[] = "NM", fm[] = "FM";
  276. X    double dm;
  277. X    int mm, ym;
  278. X    double jdn, jdf;
  279. X    int di;
  280. X
  281. X    moonnf (jd, &jdn, &jdf);
  282. X    mjd_cal (jdn-tzone/24.0, &mm, &dm, &ym);
  283. X    if (m == mm) {
  284. X        di = dm + f - 1;
  285. X        f_string (R_CAL+2+di/7, C_CAL+3*(di%7), nm);
  286. X    }
  287. X    mjd_cal (jdf-tzone/24.0, &mm, &dm, &ym);
  288. X    if (m == mm) {
  289. X        di = dm + f - 1;
  290. X        f_string (R_CAL+2+di/7, C_CAL+3*(di%7), fm);
  291. X    }
  292. X}
  293. EOFxEOF
  294. len=`wc -c < mainmenu.c`
  295. if expr $len != 6662 > /dev/null
  296. then echo Length of mainmenu.c is $len but it should be 6662.
  297. fi
  298. echo x moon.c
  299. sed -e 's/^X//' << 'EOFxEOF' > moon.c
  300. X#include <stdio.h>
  301. X#include <math.h>
  302. X#include "astro.h"
  303. X
  304. X/* given the mjd, find the geocentric ecliptic longitude, lam, and latitude,
  305. X * bet, and horizontal parallax, hp for the moon.
  306. X * N.B. series for long and lat are good to about 10 and 3 arcseconds. however,
  307. X *   math errors cause up to 100 and 30 arcseconds error, even if use double.
  308. X *   why?? suspect highly sensitive nature of difference used to get m1..6.
  309. X * N.B. still need to correct for nutation. then for topocentric location
  310. X *   further correct for parallax and refraction.
  311. X */
  312. Xmoon (mjd, lam, bet, hp)
  313. Xdouble mjd;
  314. Xdouble *lam, *bet, *hp;
  315. X{
  316. X    double t, t2;
  317. X    double ld;
  318. X    double ms;
  319. X    double md;
  320. X    double de;
  321. X    double f;
  322. X    double n;
  323. X    double a, sa, sn, b, sb, c, sc, e, e2, l, g, w1, w2;
  324. X    double m1, m2, m3, m4, m5, m6;
  325. X
  326. X    t = mjd/36525.;
  327. X    t2 = t*t;
  328. X
  329. X    m1 = mjd/27.32158213;
  330. X    m1 = 360.0*(m1-(long)m1);
  331. X    m2 = mjd/365.2596407;
  332. X    m2 = 360.0*(m2-(long)m2);
  333. X    m3 = mjd/27.55455094;
  334. X    m3 = 360.0*(m3-(long)m3);
  335. X    m4 = mjd/29.53058868;
  336. X    m4 = 360.0*(m4-(long)m4);
  337. X    m5 = mjd/27.21222039;
  338. X    m5 = 360.0*(m5-(long)m5);
  339. X    m6 = mjd/6798.363307;
  340. X    m6 = 360.0*(m6-(long)m6);
  341. X
  342. X    ld = 270.434164+m1-(.001133-.0000019*t)*t2;
  343. X    ms = 358.475833+m2-(.00015+.0000033*t)*t2;
  344. X    md = 296.104608+m3+(.009192+.0000144*t)*t2;
  345. X    de = 350.737486+m4-(.001436-.0000019*t)*t2;
  346. X    f = 11.250889+m5-(.003211+.0000003*t)*t2;
  347. X    n = 259.183275-m6+(.002078+.000022*t)*t2;
  348. X
  349. X    a = degrad(51.2+20.2*t);
  350. X    sa = sin(a);
  351. X    sn = sin(degrad(n));
  352. X    b = 346.56+(132.87-.0091731*t)*t;
  353. X    sb = .003964*sin(degrad(b));
  354. X    c = degrad(n+275.05-2.3*t);
  355. X    sc = sin(c);
  356. X    ld = ld+.000233*sa+sb+.001964*sn;
  357. X    ms = ms-.001778*sa;
  358. X    md = md+.000817*sa+sb+.002541*sn;
  359. X    f = f+sb-.024691*sn-.004328*sc;
  360. X    de = de+.002011*sa+sb+.001964*sn;
  361. X    e = 1-(.002495+7.52e-06*t)*t;
  362. X    e2 = e*e;
  363. X
  364. X    ld = degrad(ld);
  365. X    ms = degrad(ms);
  366. X    n = degrad(n);
  367. X    de = degrad(de);
  368. X    f = degrad(f);
  369. X    md = degrad(md);
  370. X
  371. X    l = 6.28875*sin(md)+1.27402*sin(2*de-md)+.658309*sin(2*de)+
  372. X        .213616*sin(2*md)-e*.185596*sin(ms)-.114336*sin(2*f)+
  373. X        .058793*sin(2*(de-md))+.057212*e*sin(2*de-ms-md)+
  374. X        .05332*sin(2*de+md)+.045874*e*sin(2*de-ms)+.041024*e*sin(md-ms);
  375. X    l = l-.034718*sin(de)-e*.030465*sin(ms+md)+.015326*sin(2*(de-f))-
  376. X        .012528*sin(2*f+md)-.01098*sin(2*f-md)+.010674*sin(4*de-md)+
  377. X        .010034*sin(3*md)+.008548*sin(4*de-2*md)-e*.00791*sin(ms-md+2*de)-
  378. X        e*.006783*sin(2*de+ms);
  379. X    l = l+.005162*sin(md-de)+e*.005*sin(ms+de)+.003862*sin(4*de)+
  380. X        e*.004049*sin(md-ms+2*de)+.003996*sin(2*(md+de))+
  381. X        .003665*sin(2*de-3*md)+e*.002695*sin(2*md-ms)+
  382. X        .002602*sin(md-2*(f+de))+e*.002396*sin(2*(de-md)-ms)-
  383. X        .002349*sin(md+de);
  384. X    l = l+e2*.002249*sin(2*(de-ms))-e*.002125*sin(2*md+ms)-
  385. X        e2*.002079*sin(2*ms)+e2*.002059*sin(2*(de-ms)-md)-
  386. X        .001773*sin(md+2*(de-f))-.001595*sin(2*(f+de))+
  387. X        e*.00122*sin(4*de-ms-md)-.00111*sin(2*(md+f))+.000892*sin(md-3*de);
  388. X    l = l-e*.000811*sin(ms+md+2*de)+e*.000761*sin(4*de-ms-2*md)+
  389. X         e2*.000704*sin(md-2*(ms+de))+e*.000693*sin(ms-2*(md-de))+
  390. X         e*.000598*sin(2*(de-f)-ms)+.00055*sin(md+4*de)+.000538*sin(4*md)+
  391. X         e*.000521*sin(4*de-ms)+.000486*sin(2*md-de);
  392. X    l = l+e2*.000717*sin(md-2*ms);
  393. X    *lam = ld+degrad(l);
  394. X    range (lam, 2*PI);
  395. X
  396. X    g = 5.12819*sin(f)+.280606*sin(md+f)+.277693*sin(md-f)+
  397. X        .173238*sin(2*de-f)+.055413*sin(2*de+f-md)+.046272*sin(2*de-f-md)+
  398. X        .032573*sin(2*de+f)+.017198*sin(2*md+f)+.009267*sin(2*de+md-f)+
  399. X        .008823*sin(2*md-f)+e*.008247*sin(2*de-ms-f);
  400. X    g = g+.004323*sin(2*(de-md)-f)+.0042*sin(2*de+f+md)+
  401. X        e*.003372*sin(f-ms-2*de)+e*.002472*sin(2*de+f-ms-md)+
  402. X        e*.002222*sin(2*de+f-ms)+e*.002072*sin(2*de-f-ms-md)+
  403. X        e*.001877*sin(f-ms+md)+.001828*sin(4*de-f-md)-e*.001803*sin(f+ms)-
  404. X        .00175*sin(3*f);
  405. X    g = g+e*.00157*sin(md-ms-f)-.001487*sin(f+de)-e*.001481*sin(f+ms+md)+
  406. X         e*.001417*sin(f-ms-md)+e*.00135*sin(f-ms)+.00133*sin(f-de)+
  407. X         .001106*sin(f+3*md)+.00102*sin(4*de-f)+.000833*sin(f+4*de-md)+
  408. X         .000781*sin(md-3*f)+.00067*sin(f+4*de-2*md);
  409. X    g = g+.000606*sin(2*de-3*f)+.000597*sin(2*(de+md)-f)+
  410. X        e*.000492*sin(2*de+md-ms-f)+.00045*sin(2*(md-de)-f)+
  411. X        .000439*sin(3*md-f)+.000423*sin(f+2*(de+md))+
  412. X        .000422*sin(2*de-f-3*md)-e*.000367*sin(ms+f+2*de-md)-
  413. X        e*.000353*sin(ms+f+2*de)+.000331*sin(f+4*de);
  414. X    g = g+e*.000317*sin(2*de+f-ms+md)+e2*.000306*sin(2*(de-ms)-f)-
  415. X        .000283*sin(md+3*f);
  416. X    w1 = .0004664*cos(n);
  417. X    w2 = .0000754*cos(c);
  418. X    *bet = degrad(g)*(1-w1-w2);
  419. X
  420. X    *hp = .950724+.051818*cos(md)+.009531*cos(2*de-md)+.007843*cos(2*de)+
  421. X          .002824*cos(2*md)+.000857*cos(2*de+md)+e*.000533*cos(2*de-ms)+
  422. X          e*.000401*cos(2*de-md-ms)+e*.00032*cos(md-ms)-.000271*cos(de)-
  423. X          e*.000264*cos(ms+md)-.000198*cos(2*f-md);
  424. X    *hp = *hp+.000173*cos(3*md)+.000167*cos(4*de-md)-e*.000111*cos(ms)+
  425. X         .000103*cos(4*de-2*md)-.000084*cos(2*md-2*de)-
  426. X         e*.000083*cos(2*de+ms)+.000079*cos(2*de+2*md)+.000072*cos(4*de)+
  427. X         e*.000064*cos(2*de-ms+md)-e*.000063*cos(2*de+ms-md)+
  428. X         e*.000041*cos(ms+de);
  429. X    *hp = *hp+e*.000035*cos(2*md-ms)-.000033*cos(3*md-2*de)-
  430. X         .00003*cos(md+de)-.000029*cos(2*(f-de))-e*.000029*cos(2*md+ms)+
  431. X         e2*.000026*cos(2*(de-ms))-.000023*cos(2*(f-de)+md)+
  432. X         e*.000019*cos(4*de-ms-md);
  433. X    *hp = degrad(*hp);
  434. X}
  435. EOFxEOF
  436. len=`wc -c < moon.c`
  437. if expr $len != 5143 > /dev/null
  438. then echo Length of moon.c is $len but it should be 5143.
  439. fi
  440. echo x moonnf.c
  441. sed -e 's/^X//' << 'EOFxEOF' > moonnf.c
  442. X#include <stdio.h>
  443. X#include <math.h>
  444. X#include "astro.h"
  445. X
  446. X#define    unw(w,z)    ((w)-floor((w)/(z))*(z))
  447. X
  448. X/* given a modified Julian date, mjd, return the mjd of the new
  449. X * and full moons about then, mjdn and mjdf.
  450. X * TODO: exactly which ones does it find? eg:
  451. X *   5/28/1988 yields 5/15 and 5/31
  452. X *   5/29             6/14     6/29
  453. X */
  454. Xmoonnf (mjd, mjdn, mjdf)
  455. Xdouble mjd;
  456. Xdouble *mjdn, *mjdf;
  457. X{
  458. X    int mo, yr;
  459. X    double dy;
  460. X    double mjd0;
  461. X    double k, tn, tf, t;
  462. X
  463. X    mjd_cal (mjd, &mo, &dy, &yr);
  464. X    cal_mjd (1, 0., yr, &mjd0);
  465. X    k = (yr-1900+((mjd-mjd0)/365))*12.3685;
  466. X    k = floor(k+0.5);
  467. X    tn = k/1236.85;
  468. X    tf = (k+0.5)/1236.85;
  469. X    t = tn;
  470. X    m (t, k, mjdn);
  471. X    t = tf;
  472. X    k += 0.5;
  473. X    m (t, k, mjdf);
  474. X}
  475. X
  476. Xstatic
  477. Xm (t, k, mjd)
  478. Xdouble t, k;
  479. Xdouble *mjd;
  480. X{
  481. X    double t2, a, a1, b, b1, c, ms, mm, f, ddjd;
  482. X
  483. X    t2 = t*t;
  484. X    a = 29.53*k;
  485. X    c = degrad(166.56+(132.87-9.173e-3*t)*t);
  486. X    b = 5.8868e-4*k+(1.178e-4-1.55e-7*t)*t2+3.3e-4*sin(c)+7.5933E-1;
  487. X    ms = 359.2242+360*unw(k/1.236886e1,1)-(3.33e-5+3.47e-6*t)*t2;
  488. X    mm = 306.0253+360*unw(k/9.330851e-1,1)+(1.07306e-2+1.236e-5*t)*t2;
  489. X    f = 21.2964+360*unw(k/9.214926e-1,1)-(1.6528e-3+2.39e-6*t)*t2;
  490. X    ms = unw(ms,360);
  491. X    mm = unw(mm,360);
  492. X    f = unw(f,360);
  493. X    ms = degrad(ms);
  494. X    mm = degrad(mm);
  495. X    f = degrad(f);
  496. X    ddjd = (1.734e-1-3.93e-4*t)*sin(ms)+2.1e-3*sin(2*ms)
  497. X        -4.068e-1*sin(mm)+1.61e-2*sin(2*mm)-4e-4*sin(3*mm)
  498. X        +1.04e-2*sin(2*f)-5.1e-3*sin(ms+mm)-7.4e-3*sin(ms-mm)
  499. X        +4e-4*sin(2*f+ms)-4e-4*sin(2*f-ms)-6e-4*sin(2*f+mm)
  500. X        +1e-3*sin(2*f-mm)+5e-4*sin(ms+2*mm);
  501. X    a1 = (long)a;
  502. X    b = b+ddjd+(a-a1);
  503. X    b1 = (long)b;
  504. X    a = a1+b1;
  505. X    b = b-b1;
  506. X    *mjd = a + b;
  507. X}
  508. EOFxEOF
  509. len=`wc -c < moonnf.c`
  510. if expr $len != 1557 > /dev/null
  511. then echo Length of moonnf.c is $len but it should be 1557.
  512. fi
  513. echo x nutation.c
  514. sed -e 's/^X//' << 'EOFxEOF' > nutation.c
  515. X#include <stdio.h>
  516. X#include <math.h>
  517. X#include "astro.h"
  518. X
  519. X/* given the modified JD, mjd, find the nutation in obliquity, *deps, and
  520. X * the nutation in longitude, *dpsi, each in radians.
  521. X */
  522. Xnutation (mjd, deps, dpsi)
  523. Xdouble mjd;
  524. Xdouble *deps, *dpsi;
  525. X{
  526. X    static double lastmjd, lastdeps, lastdpsi;
  527. X    double ls, ld;    /* sun's mean longitude, moon's mean longitude */
  528. X    double ms, md;    /* sun's mean anomaly, moon's mean anomaly */
  529. X    double nm;    /* longitude of moon's ascending node */
  530. X    double t, t2;    /* number of Julian centuries of 36525 days since
  531. X             * Jan 0.5 1900.
  532. X             */
  533. X    double tls, tnm, tld;    /* twice above */
  534. X    double a, b;    /* temps */
  535. X
  536. X    if (mjd == lastmjd) {
  537. X        *deps = lastdeps;
  538. X        *dpsi = lastdpsi;
  539. X        return;
  540. X    }
  541. X        
  542. X    t = mjd/36525.;
  543. X    t2 = t*t;
  544. X
  545. X    a = 100.0021358*t;
  546. X    b = 360.*(a-(long)a);
  547. X    ls = 279.697+.000303*t2+b;
  548. X
  549. X    a = 1336.855231*t;
  550. X    b = 360.*(a-(long)a);
  551. X    ld = 270.434-.001133*t2+b;
  552. X
  553. X    a = 99.99736056000026*t;
  554. X    b = 360.*(a-(long)a);
  555. X    ms = 358.476-.00015*t2+b;
  556. X
  557. X    a = 13255523.59*t;
  558. X    b = 360.*(a-(long)a);
  559. X    md = 296.105+.009192*t2+b;
  560. X
  561. X    a = 5.372616667*t;
  562. X    b = 360.*(a-(long)a);
  563. X    nm = 259.183+.002078*t2-b;
  564. X
  565. X    /* convert to radian forms for use with trig functions.
  566. X     */
  567. X    tls = 2*degrad(ls);
  568. X    nm = degrad(nm);
  569. X    tnm = 2*degrad(nm);
  570. X    ms = degrad(ms);
  571. X    tld = 2*degrad(ld);
  572. X    md = degrad(md);
  573. X
  574. X    /* find delta psi and eps, in arcseconds.
  575. X     */
  576. X    lastdpsi = (-17.2327-.01737*t)*sin(nm)+(-1.2729-.00013*t)*sin(tls)
  577. X           +.2088*sin(tnm)-.2037*sin(tld)+(.1261-.00031*t)*sin(ms)
  578. X           +.0675*sin(md)-(.0497-.00012*t)*sin(tls+ms)
  579. X           -.0342*sin(tld-nm)-.0261*sin(tld+md)+.0214*sin(tls-ms)
  580. X           -.0149*sin(tls-tld+md)+.0124*sin(tls-nm)+.0114*sin(tld-md);
  581. X    lastdeps = (9.21+.00091*t)*cos(nm)+(.5522-.00029*t)*cos(tls)
  582. X           -.0904*cos(tnm)+.0884*cos(tld)+.0216*cos(tls+ms)
  583. X           +.0183*cos(tld-nm)+.0113*cos(tld+md)-.0093*cos(tls-ms)
  584. X           -.0066*cos(tls-nm);
  585. X
  586. X    /* convert to radians.
  587. X     */
  588. X    lastdpsi = degrad(lastdpsi/3600);
  589. X    lastdeps = degrad(lastdeps/3600);
  590. X
  591. X    lastmjd = mjd;
  592. X    *deps = lastdeps;
  593. X    *dpsi = lastdpsi;
  594. X}
  595. EOFxEOF
  596. len=`wc -c < nutation.c`
  597. if expr $len != 2010 > /dev/null
  598. then echo Length of nutation.c is $len but it should be 2010.
  599. fi
  600. echo x objx.c
  601. sed -e 's/^X//' << 'EOFxEOF' > objx.c
  602. X/* functions to save the user-definable object.
  603. X * this way, once defined, the object can be quieried for position just like the
  604. X * other bodies, with objx_cir(). 
  605. X */
  606. X
  607. X#include <math.h>
  608. X#include "astro.h"
  609. X#include "circum.h"
  610. X#include "screen.h"
  611. X
  612. Xstatic int onflag;    /* !=0 while object x is active */
  613. X
  614. Xstatic int xtype;    /* see flags, below */
  615. X#define    FIXED        0    /* just simple ra/dec object */
  616. X#define    ELLIPTICAL    1    /* elliptical orbital elements */
  617. X#define    PARABOLIC    2    /* parabolic " */
  618. X
  619. X/* the defining info about object x.
  620. X */
  621. Xtypedef struct {
  622. X    double f_ra;    /* ra, rads, at given epoch */
  623. X    double f_dec;    /* dec, rads, at given epoch */
  624. X    double f_epoch;    /* the given epoch, as an mjd */
  625. X} ObjF;            /* fixed object */
  626. Xtypedef struct {
  627. X    double e_ep;    /* epoch of perihelion, as an mjd */
  628. X    double e_p;        /* orbital period, in (tropical?) years */
  629. X    double e_pl;    /* perihelion longitude, degrees */
  630. X    double e_q;        /* eccentricity */
  631. X    double e_inc;    /* inclination, degrees */
  632. X    double e_om;    /* longitude of ascending node, degrees */
  633. X    double e_sma;    /* semi-major axis, AU */
  634. X    double e_m1, e_m2;    /* magnitude model coefficients */
  635. X} ObjE;            /* object in heliocentric elliptical orbit */
  636. Xtypedef struct {
  637. X    double p_ep;    /* epoch of perihelion, as an mjd */
  638. X    double p_inc;    /* inclination, rads */
  639. X    double p_qp;    /* perihelion distance, AU */
  640. X    double p_ap;    /* argument of perihelion, rads. */
  641. X    double p_om;    /* longitude of ascending node, rads */
  642. X    double p_epoch;    /* reference epoch, as an mjd */
  643. X    double p_m1, p_m2;    /* magnitude model coefficients */
  644. X} ObjP;            /* object in heliocentric parabolic trajectory */
  645. X
  646. Xstatic ObjF objf;
  647. Xstatic ObjE obje;
  648. Xstatic ObjP objp;
  649. X
  650. X/* run when Objx is picked from menu.
  651. X * let op define object and turn it on and off.
  652. X */
  653. Xobjx_setup()
  654. X{
  655. X    static char *p[4] = {
  656. X        "Fixed coordinates", "Elliptical elements", "Parabolic elements"
  657. X    };
  658. X    int f;
  659. X
  660. X    /* start pointing at selection for current object type */
  661. X    switch (xtype) {
  662. X    case FIXED: f = 0; break;
  663. X    case ELLIPTICAL: f = 1; break;
  664. X    case PARABOLIC: f = 2; break;
  665. X    }
  666. X
  667. X    ask:
  668. X    p[3] = onflag ? "On" : "Off";
  669. X    switch (f = popup (p, f, 4)) {
  670. X    case 0: objx_dfixed((char**)0); goto ask;
  671. X    case 1: objx_delliptical((char**)0); goto ask;
  672. X    case 2: objx_dparabolic((char**)0); goto ask;
  673. X    case 3: onflag ^= 1; break;
  674. X    }
  675. X}
  676. X
  677. X/* turn "on" or "off" but don't forget facts about object x.
  678. X */
  679. Xobjx_on ()
  680. X{
  681. X    onflag = 1;
  682. X}
  683. X
  684. Xobjx_off()
  685. X{
  686. X    onflag = 0;
  687. X}
  688. X
  689. X/* return true if object is now on, else 0.
  690. X */
  691. Xobjx_ison()
  692. X{
  693. X    return (onflag);
  694. X}
  695. X
  696. X/* fill in info about object x.
  697. X * most arguments and conditions are the same as for plans().
  698. X * only difference is that mag is already apparent, not absolute magnitude.
  699. X * this is called by body_cir() for object x just like plans() is called
  700. X * for the planets.
  701. X */
  702. Xobjx_cir (jd, lpd0, psi0, rp0, rho0, lam, bet, mag)
  703. Xdouble jd;    /* mjd now */
  704. Xdouble *lpd0;    /* heliocentric longitude, or NOHELIO  */
  705. Xdouble *psi0;    /* heliocentric latitude, or 0 if *lpd0 set to NOHELIO */
  706. Xdouble *rp0;    /* distance from the sun, or 0 */
  707. Xdouble *rho0;    /* true distance from the Earth, or 0 */
  708. Xdouble *lam;    /* apparent geocentric ecliptic longitude */
  709. Xdouble *bet;    /* apparent geocentric ecliptic latitude */
  710. Xdouble *mag;    /* APPARENT magnitude, or NOMAG */
  711. X{
  712. X    switch (xtype) {
  713. X    case FIXED: {
  714. X        double xr, xd;
  715. X        xr = objf.f_ra;
  716. X        xd = objf.f_dec;
  717. X        if (objf.f_epoch != jd)
  718. X        precess (objf.f_epoch, jd, &xr, &xd);
  719. X        eq_ecl (jd, xr, xd, bet, lam);
  720. X
  721. X        *lpd0 = NOHELIO;
  722. X        *psi0 = *rp0 = *rho0 = 0.0;
  723. X        *mag = NOMAG;
  724. X        }
  725. X        break;
  726. X    case PARABOLIC: {
  727. X        double inc, ap, om;
  728. X        double lpd, psi, rp, rho;
  729. X        double dt;
  730. X        int pass;
  731. X        /* two passes to correct lam and bet for light travel time. */
  732. X        dt = 0.0;
  733. X        for (pass = 0; pass < 2; pass++) {
  734. X        reduce_elements (objp.p_epoch, jd-dt, objp.p_inc, objp.p_ap,
  735. X                        objp.p_om, &inc, &ap, &om);
  736. X        comet (jd-dt, objp.p_ep, inc, ap, objp.p_qp, om,
  737. X                    &lpd, &psi, &rp, &rho, lam, bet);
  738. X        if (pass == 0) {
  739. X            *lpd0 = lpd;
  740. X            *psi0 = psi;
  741. X            *rp0 = rp;
  742. X            *rho0 = rho;
  743. X        }
  744. X        dt = rho*5.775518e-3;    /* au to light-days */
  745. X        }
  746. X        *mag = objp.p_m1 + 5*log10(*rho0) + objp.p_m2*log10(*rp0);
  747. X        }
  748. X        break;
  749. X    case ELLIPTICAL: {
  750. X        /* this is basically the same code as pelement() and plans()
  751. X         * combined and simplified for the special case of osculating
  752. X         * (unperturbed) elements.
  753. X         */
  754. X        double a0, a1;
  755. X        double t, aa, ml, dayl, dt, lg, lsn, rsn;
  756. X        double nu, ea;
  757. X        double ma, rp, lp, om, lo, slo, clo;
  758. X        double inc, psi, spsi, cpsi;
  759. X        double y, lpd, rpd, ll, rho, sll, cll;
  760. X        int pass;
  761. X
  762. X        a0 = obje.e_pl - 360.0/36525.0*100.0*obje.e_ep/obje.e_p;
  763. X        a1 = 100.0/obje.e_p;
  764. X
  765. X        t = jd/36525.0;
  766. X        aa = a1*t;
  767. X        ml = a0 + 360.0*(aa - (long)aa);
  768. X        range (&ml, 360.0);
  769. X        dayl = a1*9.856263e-3;
  770. X
  771. X        dt = 0;
  772. X        sunpos (jd, &lsn, &rsn);
  773. X        lg = lsn + PI;
  774. X
  775. X        for (pass = 0; pass < 2; pass++) {
  776. X        ma = degrad(ml-obje.e_pl-dt*dayl);
  777. X        anomaly (ma, obje.e_q, &nu, &ea);
  778. X        rp = obje.e_sma*(1-obje.e_q*obje.e_q)/(1+obje.e_q*cos(nu));
  779. X        lp = raddeg(nu)+obje.e_pl;
  780. X        lp = degrad(lp);
  781. X        om = degrad(obje.e_om);
  782. X        lo = lp-om;
  783. X        slo = sin(lo);
  784. X        clo = cos(lo);
  785. X        inc = degrad(obje.e_inc);
  786. X        spsi = slo*sin(inc);
  787. X        y = slo*cos(inc);
  788. X        psi = asin(spsi);
  789. X        lpd = atan(y/clo)+om;
  790. X        if (clo<0) lpd += PI;
  791. X        range (&lpd, 2*PI);
  792. X        cpsi = cos(psi);
  793. X        rpd = rp*cpsi;
  794. X        ll = lpd-lg;
  795. X        rho = sqrt(rsn*rsn+rp*rp-2*rsn*rp*cpsi*cos(ll));
  796. X        dt = rho*5.775518e-3;
  797. X        if (pass == 0) {
  798. X            *lpd0 = lpd;
  799. X            *psi0 = psi;
  800. X            *rp0 = rp;
  801. X            *rho0 = rho;
  802. X        }
  803. X        }
  804. X
  805. X        sll = sin(ll);
  806. X        cll = cos(ll);
  807. X        *lam = atan(rsn*sll/(rpd-rsn*cll))+lpd;
  808. X        /* *lam = atan(-1*rpd*sll/(rsn-rpd*cll))+lg+PI; */
  809. X        range (lam, 2*PI);
  810. X        *bet = atan(rpd*spsi*sin(*lam-lpd)/(cpsi*rsn*sll));
  811. X        *mag = obje.e_m1 + 5*log10(*rho0) + obje.e_m2*log10(*rp0);
  812. X        }
  813. X        break;
  814. X    }
  815. X}
  816. X
  817. X/* define objx based on the ephem.cfg line, s.
  818. X * the "OBJX " keyword is already skipped.
  819. X * format: xtype,[other fields, as per corresponding ObjX typedef]
  820. X * N.B. we replace all ',' with '\0' within s IN PLACE.
  821. X * return 0 if ok, else print reason why not with f_msg() and return -1.
  822. X */
  823. Xobjx_define (s)
  824. Xchar *s;
  825. X{
  826. X#define    MAXARGS    20
  827. X    char *av[MAXARGS];    /* point to each field for easy reference */
  828. X    char c;
  829. X    int ac;
  830. X
  831. X    /* parse into comma separated fields */
  832. X    ac = 0;
  833. X    av[0] = s;
  834. X    do {
  835. X        c = *s++;
  836. X        if (c == ',' || c == '\0') {
  837. X        s[-1] = '\0';
  838. X        av[++ac] = s;
  839. X        }
  840. X    } while (c);
  841. X
  842. X    if (ac < 1) {
  843. X        f_msg ("No type for OBJX");
  844. X        return (-1);
  845. X    }
  846. X
  847. X    switch (av[0][0]) {
  848. X    case 'f':
  849. X        if (ac != 4) {
  850. X        f_msg ("Need ra,dec,epoch for \"fixed\" OBJX");
  851. X        return (-1);
  852. X        }
  853. X        objx_dfixed (av+1);
  854. X        break;
  855. X    case 'p':
  856. X        if (ac != 9) {
  857. X        f_msg ("Need ep,inc,ap,qp,om,epoch,abs,lum for \"parabolic\" OBJX");
  858. X        return (-1);
  859. X        }
  860. X        objx_dparabolic (av+1);
  861. X        break;
  862. X    case 'e':
  863. X        if (ac != 10) {
  864. X        f_msg ("Need ep,p,pl,ecc,inc,om,sma,abs,lum for \"elliptical\" OBJX");
  865. X        return (-1);
  866. X        }
  867. X        objx_delliptical (av+1);
  868. X        break;
  869. X    default:
  870. X        f_msg ("Unknown OBJX type");
  871. X        return (-1);
  872. X    }
  873. X
  874. X    return (0);
  875. X}
  876. X
  877. X/* define a fixed object.
  878. X * args in av, in order, are ra, dec, end reference epoch.
  879. X * if av then it is a list of strings to use for each parameter, else must
  880. X * ask for each. the av option is for cracking the ephem.cfg line.
  881. X * if asking show current settings and leave unchanged if hit RETURN.
  882. X * END aborts without making any more changes.
  883. X * xtype is set to FIXED.
  884. X * N.B. we don't error check av in any way, not even for length.
  885. X */
  886. Xstatic
  887. Xobjx_dfixed (av)
  888. Xchar *av[];
  889. X{
  890. X    char buf[NC];
  891. X    char *bp;
  892. X    int sts;
  893. X
  894. X    xtype = FIXED;
  895. X
  896. X    if (av) {
  897. X        bp = av[0];
  898. X        sts = 1;
  899. X    } else {
  900. X        static char p[] = "RA (h:m:s): (";
  901. X        f_prompt (p);
  902. X        f_ra (R_PROMPT, C_PROMPT+sizeof(p)-1, objf.f_ra);
  903. X        printf (") ");
  904. X        sts = read_line (buf, 8+1);
  905. X        if (sts < 0)
  906. X        return;
  907. X        bp = buf;
  908. X    }
  909. X    if (sts > 0) {
  910. X        int h, m, s;
  911. X        f_dec_sexsign (radhr(objf.f_ra), &h, &m, &s);
  912. X        f_sscansex (bp, &h, &m, &s);
  913. X        sex_dec (h, m, s, &objf.f_ra);
  914. X        objf.f_ra = hrrad(objf.f_ra);
  915. X    }
  916. X
  917. X    if (av) {
  918. X        bp = av[1];
  919. X        sts = 1;
  920. X    } else {
  921. X        static char p[] = "Dec (d:m:s): (";
  922. X        f_prompt (p);
  923. X        f_angle (R_PROMPT, C_PROMPT+sizeof(p)-1, objf.f_dec);
  924. X        printf (") ");
  925. X        sts = read_line (buf, 9+1);
  926. X        if (sts < 0)
  927. X        return;
  928. X        bp = buf;
  929. X    }
  930. X    if (sts > 0) {
  931. X        int dg, m, s;
  932. X        f_dec_sexsign (raddeg(objf.f_dec), &dg, &m, &s);
  933. X        f_sscansex (bp, &dg, &m, &s);
  934. X        sex_dec (dg, m, s, &objf.f_dec);
  935. X        objf.f_dec = degrad(objf.f_dec);
  936. X    }
  937. X
  938. X    if (av) {
  939. X        bp = av[2];
  940. X        sts = 1;
  941. X    } else {
  942. X        static char p[] = "Reference epoch (UT Date, m/d.d/y or year.d): ";
  943. X        double y;
  944. X        f_prompt (p);
  945. X        mjd_year (objf.f_epoch, &y);
  946. X        printf ("(%g) ", y);
  947. X        sts = read_line (buf, 8+1);
  948. X        if (sts < 0)
  949. X        return;
  950. X        bp = buf;
  951. X    }
  952. X    if (sts > 0)
  953. X        crack_year (bp, &objf.f_epoch);
  954. X}
  955. X
  956. X/* define an object in an elliptical heliocentric orbit.
  957. X * args in av, in order, are epoch of perihelion, orbital period, perihelion
  958. X *   longitude, eccentricity, inclination, longitude of ascending node, and
  959. X *   semi-major axis.
  960. X * if av then it is a list of strings to use for each parameter, else must
  961. X * ask for each. the av option is for cracking the ephem.cfg line.
  962. X * if asking show current settings and leave unchanged if hit RETURN.
  963. X * END aborts without making any more changes.
  964. X * xtype is set to ELLIPTICAL.
  965. X * N.B. we don't error check av in any way, not even for length.
  966. X */
  967. Xstatic
  968. Xobjx_delliptical(av)
  969. Xchar *av[];
  970. X{
  971. X    char buf[NC];
  972. X    char *bp;
  973. X    int sts;
  974. X
  975. X    xtype = ELLIPTICAL;
  976. X
  977. X    if (av) {
  978. X        bp = av[0];
  979. X        sts = 1;
  980. X    } else {
  981. X        static char p[] = 
  982. X        "Epoch of perihelion (UT Date, m/d.d/y or year.d): ";
  983. X        int m, y;
  984. X        double d;
  985. X        f_prompt (p);
  986. X        mjd_cal (obje.e_ep, &m, &d, &y);
  987. X        printf ("(%d/%g/%d) ", m, d, y);
  988. X        sts = read_line (buf, 15);
  989. X        if (sts < 0)
  990. X        return;
  991. X        bp = buf;
  992. X    }
  993. X    if (sts > 0)
  994. X        crack_year (bp, &obje.e_ep);
  995. X
  996. X    if (av) {
  997. X        bp = av[1];
  998. X        sts = 1;
  999. X    } else {
  1000. X        static char p[] = "Oribital period (years):";
  1001. X        f_prompt (p);
  1002. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", obje.e_p);
  1003. X        sts = read_line (buf, 8+1);
  1004. X        if (sts < 0)
  1005. X        return;
  1006. X        bp = buf;
  1007. X    }
  1008. X    if (sts > 0)
  1009. X        obje.e_p = atof(bp);
  1010. X
  1011. X    if (av) {
  1012. X        bp = av[2];
  1013. X        sts = 1;
  1014. X    } else {
  1015. X        static char p[] = "Perihelion longitude (degs):";
  1016. X        f_prompt (p);
  1017. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", obje.e_pl);
  1018. X        sts = read_line (buf, 8+1);
  1019. X        if (sts < 0)
  1020. X        return;
  1021. X        bp = buf;
  1022. X    }
  1023. X    if (sts > 0)
  1024. X        obje.e_pl = atof(bp);
  1025. X
  1026. X    if (av) {
  1027. X        bp = av[3];
  1028. X        sts = 1;
  1029. X    } else {
  1030. X        static char p[] = "Eccentricity:";
  1031. X        f_prompt (p);
  1032. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", obje.e_q);
  1033. X        sts = read_line (buf, 8+1);
  1034. X        if (sts < 0)
  1035. X        return;
  1036. X        bp = buf;
  1037. X    }
  1038. X    if (sts > 0)
  1039. X        obje.e_q = atof(bp);
  1040. X
  1041. X    if (av) {
  1042. X        bp = av[4];
  1043. X        sts = 1;
  1044. X    } else {
  1045. X        static char p[] = "Inclination (degs):";
  1046. X        f_prompt (p);
  1047. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", obje.e_inc);
  1048. X        sts = read_line (buf, 8+1);
  1049. X        if (sts < 0)
  1050. X        return;
  1051. X        bp = buf;
  1052. X    }
  1053. X    if (sts > 0)
  1054. X        obje.e_inc = atof(bp);
  1055. X
  1056. X    if (av) {
  1057. X        bp = av[5];
  1058. X        sts = 1;
  1059. X    } else {
  1060. X        static char p[] = "Longitude of ascending node (degs):";
  1061. X        f_prompt (p);
  1062. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", obje.e_om);
  1063. X        sts = read_line (buf, 8+1);
  1064. X        if (sts < 0)
  1065. X        return;
  1066. X        bp = buf;
  1067. X    }
  1068. X    if (sts > 0)
  1069. X        obje.e_om = atof(bp);
  1070. X
  1071. X    if (av) {
  1072. X        bp = av[6];
  1073. X        sts = 1;
  1074. X    } else {
  1075. X        static char p[] = "Semi-major axis (AU):";
  1076. X        f_prompt (p);
  1077. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", obje.e_sma);
  1078. X        sts = read_line (buf, 8+1);
  1079. X        if (sts < 0)
  1080. X        return;
  1081. X        bp = buf;
  1082. X    }
  1083. X    if (sts > 0)
  1084. X        obje.e_sma = atof(bp);
  1085. X
  1086. X    if (av) {
  1087. X        bp = av[7];
  1088. X        sts = 1;
  1089. X    } else {
  1090. X        static char p[] = "Absolute magnitude:";
  1091. X        f_prompt (p);
  1092. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", obje.e_m1);
  1093. X        sts = read_line (buf, 8+1);
  1094. X        if (sts < 0)
  1095. X        return;
  1096. X        bp = buf;
  1097. X    }
  1098. X    if (sts > 0)
  1099. X        obje.e_m1 = atof(bp);
  1100. X
  1101. X    if (av) {
  1102. X        bp = av[8];
  1103. X        sts = 1;
  1104. X    } else {
  1105. X        static char p[] = "Luminosity index:";
  1106. X        f_prompt (p);
  1107. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", obje.e_m2);
  1108. X        sts = read_line (buf, 8+1);
  1109. X        if (sts < 0)
  1110. X        return;
  1111. X        bp = buf;
  1112. X    }
  1113. X    if (sts > 0)
  1114. X        obje.e_m2 = atof(bp);
  1115. X}
  1116. X
  1117. X/* define an object in heliocentric parabolic orbit.
  1118. X * args in av, in order, are epoch of perihelion, inclination, argument of
  1119. X *   perihelion, perihelion distance, longitude of ascending node and
  1120. X *   reference epoch.
  1121. X * if av then it is a list of strings to use for each parameter, else must
  1122. X * ask for each. the av option is for cracking the ephem.cfg line.
  1123. X * if asking show current settings and leave unchanged if hit RETURN.
  1124. X * END aborts without making any more changes.
  1125. X * xtype is set to PARABOLIC.
  1126. X * N.B. we don't error check av in any way, not even for length.
  1127. X */
  1128. Xstatic
  1129. Xobjx_dparabolic(av)
  1130. Xchar *av[];
  1131. X{
  1132. X    char buf[NC];
  1133. X    char *bp;
  1134. X    int sts;
  1135. X
  1136. X    xtype = PARABOLIC;
  1137. X
  1138. X    if (av) {
  1139. X        bp = av[0];
  1140. X        sts = 1;
  1141. X    } else {
  1142. X        static char p[] =
  1143. X        "Epoch of perihelion (UT Date, m/d.d/y or year.d): ";
  1144. X        int m, y;
  1145. X        double d;
  1146. X        f_prompt (p);
  1147. X        mjd_cal (objp.p_ep, &m, &d, &y);
  1148. X        printf ("(%d/%g/%d) ", m, d, y);
  1149. X        sts = read_line (buf, PW-sizeof(p));
  1150. X        if (sts < 0)
  1151. X        return;
  1152. X        bp = buf;
  1153. X    }
  1154. X    if (sts > 0)
  1155. X        crack_year (bp, &objp.p_ep);
  1156. X
  1157. X    if (av) {
  1158. X        bp = av[1];
  1159. X        sts = 1;
  1160. X    } else {
  1161. X        static char p[] = "Inclination (degs):";
  1162. X        f_prompt (p);
  1163. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ",raddeg(objp.p_inc));
  1164. X        sts = read_line (buf, 8+1);
  1165. X        if (sts < 0)
  1166. X        return;
  1167. X        bp = buf;
  1168. X    }
  1169. X    if (sts > 0)
  1170. X        objp.p_inc = degrad(atof(bp));
  1171. X
  1172. X    if (av) {
  1173. X        bp = av[2];
  1174. X        sts = 1;
  1175. X    } else {
  1176. X        static char p[] = "Argument of perihelion (degs):";
  1177. X        f_prompt (p);
  1178. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", raddeg(objp.p_ap));
  1179. X        sts = read_line (buf, 8+1);
  1180. X        if (sts < 0)
  1181. X        return;
  1182. X        bp = buf;
  1183. X    }
  1184. X    if (sts > 0)
  1185. X        objp.p_ap = degrad(atof(bp));
  1186. X
  1187. X    if (av) {
  1188. X        bp = av[3];
  1189. X        sts = 1;
  1190. X    } else {
  1191. X        static char p[] = "Perihelion distance (AU):";
  1192. X        f_prompt (p);
  1193. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", objp.p_qp);
  1194. X        sts = read_line (buf, 8+1);
  1195. X        if (sts < 0)
  1196. X        return;
  1197. X        bp = buf;
  1198. X    }
  1199. X    if (sts > 0)
  1200. X        objp.p_qp = atof(bp);
  1201. X
  1202. X    if (av) {
  1203. X        bp = av[4];
  1204. X        sts = 1;
  1205. X    } else {
  1206. X        static char p[] = "Longitude of ascending node (degs):";
  1207. X        f_prompt (p);
  1208. X        f_double(R_PROMPT,C_PROMPT+sizeof(p), "(%g) ", raddeg(objp.p_om));
  1209. X        sts = read_line (buf, 8+1);
  1210. X        if (sts < 0)
  1211. X        return;
  1212. X        bp = buf;
  1213. X    }
  1214. X    if (sts > 0)
  1215. X        objp.p_om = degrad(atof(bp));
  1216. X
  1217. X    if (av) {
  1218. X        bp = av[5];
  1219. X        sts = 1;
  1220. X    } else {
  1221. X        static char p[] = "Reference epoch (UT Date, m/d.d/y or year.d): ";
  1222. X        double y;
  1223. X        f_prompt (p);
  1224. X        mjd_year (objp.p_epoch, &y);
  1225. X        printf ("(%g) ", y);
  1226. X        sts = read_line (buf, 8+1);
  1227. X        if (sts < 0)
  1228. X        return;
  1229. X        bp = buf;
  1230. X    }
  1231. X    if (sts > 0)
  1232. X        crack_year (bp, &objp.p_epoch);
  1233. X
  1234. X    if (av) {
  1235. X        bp = av[6];
  1236. X        sts = 1;
  1237. X    } else {
  1238. X        static char p[] = "Absolute magnitude:";
  1239. X        f_prompt (p);
  1240. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", objp.p_m1);
  1241. X        sts = read_line (buf, 8+1);
  1242. X        if (sts < 0)
  1243. X        return;
  1244. X        bp = buf;
  1245. X    }
  1246. X    if (sts > 0)
  1247. X        objp.p_m1 = atof(bp);
  1248. X
  1249. X    if (av) {
  1250. X        bp = av[7];
  1251. X        sts = 1;
  1252. X    } else {
  1253. X        static char p[] = "Luminosity index:";
  1254. X        f_prompt (p);
  1255. X        f_double (R_PROMPT, C_PROMPT+sizeof(p), "(%g) ", objp.p_m2);
  1256. X        sts = read_line (buf, 8+1);
  1257. X        if (sts < 0)
  1258. X        return;
  1259. X        bp = buf;
  1260. X    }
  1261. X    if (sts > 0)
  1262. X        objp.p_m2 = atof(bp);
  1263. X}
  1264. X
  1265. X/* given either a decimal year (xxxx. something) or a calendar (x/x/x)
  1266. X * convert it to an mjd and store it at *p;
  1267. X */
  1268. Xstatic
  1269. Xcrack_year (bp, p)
  1270. Xchar *bp;
  1271. Xdouble *p;
  1272. X{
  1273. X    if (decimal_year(bp)) {
  1274. X        double y = atof (bp);
  1275. X        year_mjd (y, p);
  1276. X    } else {
  1277. X        int m, y;
  1278. X        double d;
  1279. X        mjd_cal (objp.p_ep, &m, &d, &y);    /* init with current */
  1280. X        f_sscandate (bp, &m, &d, &y);
  1281. X        cal_mjd (m, d, y, p);
  1282. X    }
  1283. X}
  1284. EOFxEOF
  1285. len=`wc -c < objx.c`
  1286. if expr $len != 16243 > /dev/null
  1287. then echo Length of objx.c is $len but it should be 16243.
  1288. fi
  1289. echo x obliq.c
  1290. sed -e 's/^X//' << 'EOFxEOF' > obliq.c
  1291. X#include <stdio.h>
  1292. X#include "astro.h"
  1293. X
  1294. X/* given the modified Julian date, mjd, find the obliquity of the
  1295. X * ecliptic, *eps, in radians.
  1296. X */
  1297. Xobliquity (mjd, eps)
  1298. Xdouble mjd;
  1299. Xdouble *eps;
  1300. X{
  1301. X    static double lastmjd, lasteps;
  1302. X
  1303. X    if (mjd != lastmjd) {
  1304. X        double t;
  1305. X        t = mjd/36525.;
  1306. X        lasteps = degrad(2.345229444E1 - ((((-1.81E-3*t)+5.9E-3)*t+4.6845E1)*t)/3600.0);
  1307. X        lastmjd = mjd;
  1308. X    }
  1309. X    *eps = lasteps;
  1310. X}
  1311. EOFxEOF
  1312. len=`wc -c < obliq.c`
  1313. if expr $len != 409 > /dev/null
  1314. then echo Length of obliq.c is $len but it should be 409.
  1315. fi
  1316. echo x parallax.c
  1317. sed -e 's/^X//' << 'EOFxEOF' > parallax.c
  1318. X#include <stdio.h>
  1319. X#include <math.h>
  1320. X#include "astro.h"
  1321. X
  1322. X/* given true ha and dec, tha and tdec, the geographical latitude, phi, the
  1323. X * height above sea-level (as a fraction of the earths radius, 6378.16km),
  1324. X * ht, and the equatorial horizontal parallax, ehp, find the apparent
  1325. X * ha and dec, aha and adec allowing for parallax.
  1326. X * all angles in radians. ehp is the angle subtended at the body by the
  1327. X * earth's equator.
  1328. X */
  1329. Xta_par (tha, tdec, phi, ht, ehp, aha, adec)
  1330. Xdouble tha, tdec, phi, ht, ehp;
  1331. Xdouble *aha, *adec;
  1332. X{
  1333. X    static double last_phi, last_ht, rsp, rcp;
  1334. X    double rp;    /* distance to object in Earth radii */
  1335. X    double ctha;
  1336. X    double stdec, ctdec;
  1337. X    double tdtha, dtha;
  1338. X    double caha;
  1339. X
  1340. X    /* avoid calcs involving the same phi and ht */
  1341. X    if (phi != last_phi || ht != last_ht) {
  1342. X        double cphi, sphi, u;
  1343. X        cphi = cos(phi);
  1344. X        sphi = sin(phi);
  1345. X        u = atan(9.96647e-1*sphi/cphi);
  1346. X        rsp = (9.96647e-1*sin(u))+(ht*sphi);
  1347. X        rcp = cos(u)+(ht*cphi);
  1348. X        last_phi  =  phi;
  1349. X        last_ht  =  ht;
  1350. X    }
  1351. X
  1352. X        rp = 1/sin(ehp);
  1353. X
  1354. X        ctha = cos(tha);
  1355. X    stdec = sin(tdec);
  1356. X    ctdec = cos(tdec);
  1357. X        tdtha = (rcp*sin(tha))/((rp*ctdec)-(rcp*ctha));
  1358. X        dtha = atan(tdtha);
  1359. X    *aha = tha+dtha;
  1360. X    caha = cos(*aha);
  1361. X    range (aha, 2*PI);
  1362. X        *adec = atan(caha*(rp*stdec-rsp)/(rp*ctdec*ctha-rcp));
  1363. X}
  1364. X
  1365. X/* given the apparent ha and dec, aha and adec, the geographical latitude, phi,
  1366. X * the height above sea-level (as a fraction of the earths radius, 6378.16km),
  1367. X * ht, and the equatorial horizontal parallax, ehp, find the true ha and dec,
  1368. X * tha and tdec allowing for parallax.
  1369. X * all angles in radians. ehp is the angle subtended at the body by the
  1370. X * earth's equator.
  1371. X * uses ta_par() iteratively: find a set of true ha/dec that converts back
  1372. X  *  to the given apparent ha/dec.
  1373. X */
  1374. Xat_par (aha, adec, phi, ht, ehp, tha, tdec)
  1375. Xdouble aha, adec, phi, ht, ehp;
  1376. Xdouble *tha, *tdec;
  1377. X{
  1378. X    double nha, ndec;    /* ha/dec corres. to current true guesses */
  1379. X    double eha, edec;    /* error in ha/dec */
  1380. X
  1381. X    /* first guess for true is just the apparent */
  1382. X    *tha = aha;
  1383. X    *tdec = adec;
  1384. X
  1385. X    while (1) {
  1386. X        ta_par (*tha, *tdec, phi, ht, ehp, &nha, &ndec);
  1387. X        eha = aha - nha;
  1388. X        edec = adec - ndec;
  1389. X        if (fabs(eha)<1e-6 && fabs(edec)<1e-6)
  1390. X        break;
  1391. X        *tha += eha;
  1392. X        *tdec += edec;
  1393. X    }
  1394. X}
  1395. EOFxEOF
  1396. len=`wc -c < parallax.c`
  1397. if expr $len != 2280 > /dev/null
  1398. then echo Length of parallax.c is $len but it should be 2280.
  1399. fi
  1400. echo x pelement.c
  1401. sed -e 's/^X//' << 'EOFxEOF' > pelement.c
  1402. X#include <stdio.h>
  1403. X#include <math.h>
  1404. X#include "astro.h"
  1405. X
  1406. X/* this array contains polynomial coefficients to find the various orbital
  1407. X *   elements for the mean orbit at any instant in time for each major planet.
  1408. X *   the first five elements are in the form a0 + a1*t + a2*t**2 + a3*t**3,
  1409. X *   where t is the number of Julian centuries of 36525 Julian days since 1900
  1410. X *   Jan 0.5. the last three elements are constants.
  1411. X *
  1412. X * the orbital element (column) indeces are:
  1413. X *   [ 0- 3]: coefficients for mean longitude, in degrees;
  1414. X *   [ 4- 7]: coefficients for longitude of the perihelion, in degrees;
  1415. X *   [ 8-11]: coefficients for eccentricity;
  1416. X *   [12-15]: coefficients for inclination, in degrees;
  1417. X *   [16-19]: coefficients for longitude of the ascending node, in degrees;
  1418. X *      [20]: semi-major axis, in AU;
  1419. X *      [21]: angular diameter at 1 AU, in arcsec;
  1420. X *      [22]: standard visual magnitude, ie, the visual magnitude of the planet
  1421. X *          when at a distance of 1 AU from both the Sun and the Earth and
  1422. X *          with zero phase angle.
  1423. X *
  1424. X * the planent (row) indeces are:
  1425. X *   [0]: Mercury; [1]: Venus;   [2]: Mars;  [3]: Jupiter; [4]: Saturn;
  1426. X *   [5]: Uranus;  [6]: Neptune; [7]: Pluto.
  1427. X */
  1428. X#define    NPELE    (5*4 + 3)    /* 4 coeffs for ea of 5 elems, + 3 constants */
  1429. Xstatic double elements[8][NPELE] = {
  1430. X
  1431. X    {   /*     mercury... */
  1432. X
  1433. X        178.179078,    415.2057519,    3.011e-4,    0.0,
  1434. X        75.899697,    1.5554889,    2.947e-4,    0.0,
  1435. X        .20561421,    2.046e-5,    3e-8,        0.0,
  1436. X        7.002881,    1.8608e-3,    -1.83e-5,    0.0,
  1437. X        47.145944,    1.1852083,    1.739e-4,    0.0,
  1438. X        .3870986,    6.74,         -0.42
  1439. X    },
  1440. X
  1441. X    {   /*     venus... */
  1442. X
  1443. X        342.767053,    162.5533664,    3.097e-4,    0.0,
  1444. X        130.163833,    1.4080361,    -9.764e-4,    0.0,
  1445. X        6.82069e-3,    -4.774e-5,    9.1e-8,        0.0,
  1446. X        3.393631,    1.0058e-3,    -1e-6,        0.0,
  1447. X        75.779647,    .89985,        4.1e-4,        0.0,
  1448. X        .7233316,    16.92,        -4.4
  1449. X    },
  1450. X
  1451. X    {   /*     mars... */
  1452. X
  1453. X        293.737334,    53.17137642,    3.107e-4,    0.0,
  1454. X        3.34218203e2, 1.8407584,    1.299e-4,    -1.19e-6,
  1455. X        9.33129e-2,    9.2064e-5,    7.7e-8,        0.0,
  1456. X        1.850333,    -6.75e-4,    1.26e-5,    0.0,
  1457. X        48.786442,    .7709917,    -1.4e-6,    -5.33e-6,
  1458. X        1.5236883,    9.36,        -1.52
  1459. X    },
  1460. X
  1461. X    {   /*     jupiter... */
  1462. X
  1463. X        238.049257,    8.434172183,    3.347e-4,    -1.65e-6,
  1464. X        1.2720972e1, 1.6099617,    1.05627e-3,    -3.43e-6,
  1465. X        4.833475e-2, 1.6418e-4,    -4.676e-7,    -1.7e-9,
  1466. X        1.308736,    -5.6961e-3,    3.9e-6,        0.0,
  1467. X        99.443414,    1.01053,    3.5222e-4,    -8.51e-6,
  1468. X        5.202561,    196.74,        -9.4
  1469. X    },
  1470. X
  1471. X    {   /*     saturn... */
  1472. X
  1473. X        266.564377,    3.398638567,    3.245e-4,    -5.8e-6,
  1474. X        9.1098214e1, 1.9584158,    8.2636e-4,    4.61e-6,
  1475. X        5.589232e-2, -3.455e-4,    -7.28e-7,    7.4e-10,
  1476. X        2.492519,    -3.9189e-3,    -1.549e-5,    4e-8,
  1477. X        112.790414,    .8731951,    -1.5218e-4,    -5.31e-6,
  1478. X        9.554747,    165.6,        -8.88
  1479. X    },
  1480. X
  1481. X    {   /*     uranus... */
  1482. X
  1483. X        244.19747,    1.194065406,    3.16e-4,    -6e-7,
  1484. X        1.71548692e2, 1.4844328,    2.372e-4,    -6.1e-7,
  1485. X        4.63444e-2,    -2.658e-5,    7.7e-8,        0.0,
  1486. X        .772464,    6.253e-4,    3.95e-5,    0.0,
  1487. X        73.477111,    .4986678,    1.3117e-3,    0.0,
  1488. X        19.21814,    65.8,        -7.19
  1489. X    },
  1490. X
  1491. X    {   /*     neptune... */
  1492. X
  1493. X        84.457994,    .6107942056,    3.205e-4,    -6e-7,
  1494. X        4.6727364e1, 1.4245744,    3.9082e-4,    -6.05e-7,
  1495. X        8.99704e-3,    6.33e-6,    -2e-9,        0.0,
  1496. X        1.779242,    -9.5436e-3,    -9.1e-6,    0.0,
  1497. X        130.681389,    1.098935,    2.4987e-4,    -4.718e-6,
  1498. X        30.10957,    62.2,        -6.87
  1499. X    },
  1500. X
  1501. X    {   /*     pluto...(osculating 1984 jan 21) */
  1502. X
  1503. X        95.3113544,    .3980332167,    0.0,        0.0,
  1504. X        224.017,    0.0,        0.0,        0.0,
  1505. X        .25515,    0.0,        0.0,        0.0,
  1506. X        17.1329,    0.0,        0.0,        0.0,
  1507. X        110.191,    0.0,        0.0,        0.0,
  1508. X        39.8151,    8.2,        -1.0
  1509. X    }
  1510. X};
  1511. X
  1512. X/* given a modified Julian date, mjd, return the elements for the mean orbit
  1513. X *   at that instant of all the major planets, together with their
  1514. X *   mean daily motions in longitude, angular diameter and standard visual
  1515. X *   magnitude.
  1516. X * plan[i][j] contains all the values for all the planets at mjd, such that
  1517. X *   i = 0..7: mercury, venus, mars, jupiter, saturn, unranus, neptune, pluto;
  1518. X *   j = 0..8: mean longitude, mean daily motion in longitude, longitude of 
  1519. X *     the perihelion, eccentricity, inclination, longitude of the ascending
  1520. X *     node, length of the semi-major axis, angular diameter from 1 AU, and
  1521. X *     the standard visual magnitude (see elements[][] comment, above).
  1522. X */
  1523. Xpelement (mjd, plan)
  1524. Xdouble mjd;
  1525. Xdouble plan[8][9];
  1526. X{
  1527. X    register double *ep, *pp;
  1528. X    register double t = mjd/36525.;
  1529. X    double aa;
  1530. X    int planet, i;
  1531. X
  1532. X    for (planet = 0; planet < 8; planet++) {
  1533. X        ep = elements[planet];
  1534. X        pp = plan[planet];
  1535. X        aa = ep[1]*t;
  1536. X        pp[0] = ep[0] + 360.*(aa-(long)aa) + (ep[3]*t + ep[2])*t*t;
  1537. X        range (pp, 360.);
  1538. X        pp[1] = (ep[1]*9.856263e-3) + (ep[2] + ep[3])/36525;
  1539. X
  1540. X        for (i = 4; i < 20; i += 4)
  1541. X        pp[i/4+1] = ((ep[i+3]*t + ep[i+2])*t + ep[i+1])*t + ep[i+0];
  1542. X
  1543. X        pp[6] = ep[20];
  1544. X        pp[7] = ep[21];
  1545. X        pp[8] = ep[22];
  1546. X    }
  1547. X}
  1548. EOFxEOF
  1549. len=`wc -c < pelement.c`
  1550. if expr $len != 4797 > /dev/null
  1551. then echo Length of pelement.c is $len but it should be 4797.
  1552. fi
  1553. echo x plans.c
  1554. sed -e 's/^X//' << 'EOFxEOF' > plans.c
  1555. X#include <stdio.h>
  1556. X#include <math.h>
  1557. X#include "astro.h"
  1558. X
  1559. X#define    TWOPI        (2*PI)
  1560. X#define    mod2PI(x)    ((x) - (long)((x)/TWOPI)*TWOPI)
  1561. X
  1562. X/* given a modified Julian date, mjd, and a planet, p, find:
  1563. X *   lpd0: heliocentric longitude, 
  1564. X *   psi0: heliocentric latitude,
  1565. X *   rp0:  distance from the sun to the planet, 
  1566. X *   rho0: distance from the Earth to the planet,
  1567. X *         none corrected for light time, ie, they are the true values for the
  1568. X *         given instant.
  1569. X *   lam:  geocentric ecliptic longitude, 
  1570. X *   bet:  geocentric ecliptic latitude,
  1571. X *         each corrected for light time, ie, they are the apparent values as
  1572. X *       seen from the center of the Earth for the given instant.
  1573. X *   dia:  angular diameter in arcsec at 1 AU, 
  1574. X *   mag:  visual magnitude when 1 AU from sun and earth at 0 phase angle.
  1575. X *
  1576. X * all angles are in radians, all distances in AU.
  1577. X * the mean orbital elements are found by calling pelement(), then mutual
  1578. X *   perturbation corrections are applied as necessary.
  1579. X *
  1580. X * corrections for nutation and abberation must be made by the caller. The RA 
  1581. X *   and DEC calculated from the fully-corrected ecliptic coordinates are then
  1582. X *   the apparent geocentric coordinates. Further corrections can be made, if
  1583. X *   required, for atmospheric refraction and geocentric parallax although the
  1584. X *   intrinsic error herein of about 10 arcseconds is usually the dominant
  1585. X *   error at this stage.
  1586. X * TODO: combine the several intermediate expressions when get a good compiler.
  1587. X */
  1588. Xplans (mjd, p, lpd0, psi0, rp0, rho0, lam, bet, dia, mag)
  1589. Xdouble mjd;
  1590. Xint p;
  1591. Xdouble *lpd0, *psi0, *rp0, *rho0, *lam, *bet, *dia, *mag;
  1592. X{
  1593. X    static double plan[8][9];
  1594. X    static double lastmjd = -10000;
  1595. X    double dl;    /* perturbation correction for longitude */
  1596. X    double dr;    /*  "   orbital radius */
  1597. X    double dml;    /*  "   mean longitude */
  1598. X    double ds;    /*  "   eccentricity */
  1599. X    double dm;    /*  "   mean anomaly */
  1600. X    double da;    /*  "   semi-major axis */
  1601. X    double dhl;    /*  "   heliocentric longitude */
  1602. X    double lsn, rsn;    /* true geocentric longitude of sun and sun-earth rad */
  1603. X    double mas;    /* mean anomaly of the sun */
  1604. X    double re;    /* radius of earth's orbit */
  1605. X    double lg;    /* longitude of earth */
  1606. X    double map[8];    /* array of mean anomalies for each planet */
  1607. X    double lpd, psi, rp, rho;
  1608. X    double ll, sll, cll;
  1609. X    double t;
  1610. X    double dt;
  1611. X    int pass;
  1612. X    int j;
  1613. X    double s, ma;
  1614. X    double nu, ea;
  1615. X    double lp, om;
  1616. X    double lo, slo, clo;
  1617. X    double inc, y;
  1618. X    double spsi, cpsi;
  1619. X    double rpd;
  1620. X
  1621. X    /* only need to fill in plan[] once for a given mjd */
  1622. X    if (mjd != lastmjd) {
  1623. X        pelement (mjd, plan);
  1624. X        lastmjd = mjd;
  1625. X    }
  1626. X
  1627. X    dt = 0;
  1628. X    t = mjd/36525.;
  1629. X    sunpos (mjd, &lsn, &rsn);
  1630. X    masun (mjd, &mas);
  1631. X        re = rsn;
  1632. X    lg = lsn+PI;
  1633. X
  1634. X    /* first find the true position of the planet at mjd.
  1635. X     * then repeat a second time for a slightly different time based
  1636. X     * on the position found in the first pass to account for light-travel
  1637. X     * time.
  1638. X     */
  1639. X    for (pass = 0; pass < 2; pass++) {
  1640. X
  1641. X        for (j = 0; j < 8; j++)
  1642. X        map[j] = degrad(plan[j][0]-plan[j][2]-dt*plan[j][1]);
  1643. X
  1644. X        /* set initial corrections to 0.
  1645. X         * then modify as necessary for the planet of interest.
  1646. X         */
  1647. X        dl = 0;
  1648. X        dr = 0;
  1649. X        dml = 0;
  1650. X        ds = 0;
  1651. X        dm = 0;
  1652. X        da = 0;
  1653. X        dhl = 0;
  1654. X
  1655. X        switch (p) {
  1656. X
  1657. X        case MERCURY:
  1658. X        p_mercury (map, &dl, &dr);
  1659. X        break;
  1660. X
  1661. X        case VENUS:
  1662. X        p_venus (t, mas, map, &dl, &dr, &dml, &dm);
  1663. X        break;
  1664. X
  1665. X        case MARS:
  1666. X        p_mars (mas, map, &dl, &dr, &dml, &dm);
  1667. X        break;
  1668. X
  1669. X        case JUPITER:
  1670. X        p_jupiter (t, plan[p][3], &dml, &ds, &dm, &da);
  1671. X        break;
  1672. X
  1673. X        case SATURN:
  1674. X        p_saturn (t, plan[p][3], &dml, &ds, &dm, &da, &dhl);
  1675. X        break;
  1676. X
  1677. X        case URANUS:
  1678. X        p_uranus (t, plan[p][3], &dl, &dr, &dml, &ds, &dm, &da, &dhl);
  1679. X        break;
  1680. X
  1681. X        case NEPTUNE:
  1682. X        p_neptune (t, plan[p][3], &dl, &dr, &dml, &ds, &dm, &da, &dhl);
  1683. X        break;
  1684. X
  1685. X        case PLUTO:
  1686. X        /* no perturbation theory for pluto */
  1687. X        break;
  1688. X        }
  1689. X
  1690. X        s = plan[p][3]+ds;
  1691. X        ma = map[p]+dm;
  1692. X        anomaly (ma, s, &nu, &ea);
  1693. X        rp = (plan[p][6]+da)*(1-s*s)/(1+s*cos(nu));
  1694. X        lp = raddeg(nu)+plan[p][2]+raddeg(dml-dm);
  1695. X        lp = degrad(lp);
  1696. X        om = degrad(plan[p][5]);
  1697. X        lo = lp-om;
  1698. X        slo = sin(lo);
  1699. X        clo = cos(lo);
  1700. X        inc = degrad(plan[p][4]);
  1701. X        rp = rp+dr;
  1702. X        spsi = slo*sin(inc);
  1703. X        y = slo*cos(inc);
  1704. X        psi = asin(spsi)+dhl;
  1705. X        spsi = sin(psi);
  1706. X        lpd = atan(y/clo)+om+degrad(dl);
  1707. X        if (clo<0) lpd += PI;
  1708. X        range (&lpd, TWOPI);
  1709. X        cpsi = cos(psi);
  1710. X        rpd = rp*cpsi;
  1711. X        ll = lpd-lg;
  1712. X        rho = sqrt(re*re+rp*rp-2*re*rp*cpsi*cos(ll));
  1713. X
  1714. X        /* when we view a planet we see it in the position it occupied
  1715. X         * dt days ago, where rho is the distance between it and earth,
  1716. X         * in AU. use this as the new time for the next pass.
  1717. X         */
  1718. X        dt = rho*5.775518e-3;
  1719. X
  1720. X        if (pass == 0) {
  1721. X        /* save heliocentric coordinates after first pass since, being
  1722. X         * true, they are NOT to be corrected for light-travel time.
  1723. X         */
  1724. X        *lpd0 = lpd;
  1725. X        range (lpd0, TWOPI);
  1726. X        *psi0 = psi;
  1727. X        *rp0 = rp;
  1728. X        *rho0 = rho;
  1729. X        }
  1730. X    }
  1731. X
  1732. X        sll = sin(ll);
  1733. X    cll = cos(ll);
  1734. X        if (p < MARS) 
  1735. X        *lam = atan(-1*rpd*sll/(re-rpd*cll))+lg+PI;
  1736. X    else
  1737. X        *lam = atan(re*sll/(rpd-re*cll))+lpd;
  1738. X    range (lam, TWOPI);
  1739. X        *bet = atan(rpd*spsi*sin(*lam-lpd)/(cpsi*re*sll));
  1740. X    *dia = plan[p][7];
  1741. X    *mag = plan[p][8];
  1742. X}
  1743. X
  1744. X/* set auxilliary variables used for jupiter, saturn, uranus, and neptune */
  1745. Xstatic
  1746. Xaux_jsun (t, x1, x2, x3, x4, x5, x6)
  1747. Xdouble t;
  1748. Xdouble *x1, *x2, *x3, *x4, *x5, *x6;
  1749. X{
  1750. X        *x1 = t/5+0.1;
  1751. X        *x2 = mod2PI(4.14473+5.29691e1*t);
  1752. X        *x3 = mod2PI(4.641118+2.132991e1*t);
  1753. X        *x4 = mod2PI(4.250177+7.478172*t);
  1754. X        *x5 = 5 * *x3 - 2 * *x2;
  1755. X    *x6 = 2 * *x2 - 6 * *x3 + 3 * *x4;
  1756. X}
  1757. X
  1758. X/* find the mean anomaly of the sun at mjd.
  1759. X * this is the same as that used in sun() but when it was converted to C it
  1760. X * was not known it would be required outside that routine.
  1761. X * TODO: add an argument to sun() to return mas and eliminate this routine.
  1762. X */
  1763. Xstatic
  1764. Xmasun (mjd, mas)
  1765. Xdouble mjd;
  1766. Xdouble *mas;
  1767. X{
  1768. X    double t, t2;
  1769. X    double a, b;
  1770. X
  1771. X    t = mjd/36525;
  1772. X    t2 = t*t;
  1773. X    a = 9.999736042e1*t;
  1774. X    b = 360.*(a-(long)a);
  1775. X    *mas = degrad (3.5847583e2-(1.5e-4+3.3e-6*t)*t2+b);
  1776. X}
  1777. X
  1778. X/* perturbations for mercury */
  1779. Xstatic
  1780. Xp_mercury (map, dl, dr)
  1781. Xdouble map[];
  1782. Xdouble *dl, *dr;
  1783. X{
  1784. X    *dl = 2.04e-3*cos(5*map[2-1]-2*map[1-1]+2.1328e-1)+
  1785. X         1.03e-3*cos(2*map[2-1]-map[1-1]-2.8046)+
  1786. X         9.1e-4*cos(2*map[3]-map[1-1]-6.4582e-1)+
  1787. X         7.8e-4*cos(5*map[2-1]-3*map[1-1]+1.7692e-1);
  1788. X
  1789. X    *dr = 7.525e-6*cos(2*map[3]-map[1-1]+9.25251e-1)+
  1790. X         6.802e-6*cos(5*map[2-1]-3*map[1-1]-4.53642)+
  1791. X         5.457e-6*cos(2*map[2-1]-2*map[1-1]-1.24246)+
  1792. X         3.569e-6*cos(5*map[2-1]-map[1-1]-1.35699);
  1793. X}
  1794. X
  1795. X/* ....venus */
  1796. Xstatic
  1797. Xp_venus (t, mas, map, dl, dr, dml, dm)
  1798. Xdouble t, mas, map[];
  1799. Xdouble *dl, *dr, *dml, *dm;
  1800. X{
  1801. X    *dml = degrad (7.7e-4*sin(4.1406+t*2.6227));
  1802. X    *dm = *dml;
  1803. X
  1804. X    *dl = 3.13e-3*cos(2*mas-2*map[2-1]-2.587)+
  1805. X         1.98e-3*cos(3*mas-3*map[2-1]+4.4768e-2)+
  1806. X         1.36e-3*cos(mas-map[2-1]-2.0788)+
  1807. X         9.6e-4*cos(3*mas-2*map[2-1]-2.3721)+
  1808. X         8.2e-4*cos(map[3]-map[2-1]-3.6318);
  1809. X
  1810. X    *dr = 2.2501e-5*cos(2*mas-2*map[2-1]-1.01592)+
  1811. X         1.9045e-5*cos(3*mas-3*map[2-1]+1.61577)+
  1812. X         6.887e-6*cos(map[3]-map[2-1]-2.06106)+
  1813. X         5.172e-6*cos(mas-map[2-1]-5.08065e-1)+
  1814. X         3.62e-6*cos(5*mas-4*map[2-1]-1.81877)+
  1815. X         3.283e-6*cos(4*mas-4*map[2-1]+1.10851)+
  1816. X         3.074e-6*cos(2*map[3]-2*map[2-1]-9.62846e-1);
  1817. X}
  1818. X
  1819. X/* ....mars */
  1820. Xstatic
  1821. Xp_mars (mas, map, dl, dr, dml, dm)
  1822. Xdouble mas, map[];
  1823. Xdouble *dl, *dr, *dml, *dm;
  1824. X{
  1825. X    double a;
  1826. X
  1827. X    a = 3*map[3]-8*map[2]+4*mas;
  1828. X    *dml = degrad (-1*(1.133e-2*sin(a)+9.33e-3*cos(a)));
  1829. X    *dm = *dml;
  1830. X
  1831. X    *dl = 7.05e-3*cos(map[3]-map[2]-8.5448e-1)+
  1832. X         6.07e-3*cos(2*map[3]-map[2]-3.2873)+
  1833. X         4.45e-3*cos(2*map[3]-2*map[2]-3.3492)+
  1834. X         3.88e-3*cos(mas-2*map[2]+3.5771e-1)+
  1835. X         2.38e-3*cos(mas-map[2]+6.1256e-1)+
  1836. X         2.04e-3*cos(2*mas-3*map[2]+2.7688)+
  1837. X         1.77e-3*cos(3*map[2]-map[2-1]-1.0053)+
  1838. X         1.36e-3*cos(2*mas-4*map[2]+2.6894)+
  1839. X         1.04e-3*cos(map[3]+3.0749e-1);
  1840. X
  1841. X    *dr = 5.3227e-5*cos(map[3]-map[2]+7.17864e-1)+
  1842. X         5.0989e-5*cos(2*map[3]-2*map[2]-1.77997)+
  1843. X         3.8278e-5*cos(2*map[3]-map[2]-1.71617)+
  1844. X         1.5996e-5*cos(mas-map[2]-9.69618e-1)+
  1845. X         1.4764e-5*cos(2*mas-3*map[2]+1.19768)+
  1846. X         8.966e-6*cos(map[3]-2*map[2]+7.61225e-1);
  1847. X     *dr += 7.914e-6*cos(3*map[3]-2*map[2]-2.43887)+
  1848. X         7.004e-6*cos(2*map[3]-3*map[2]-1.79573)+
  1849. X         6.62e-6*cos(mas-2*map[2]+1.97575)+
  1850. X         4.93e-6*cos(3*map[3]-3*map[2]-1.33069)+
  1851. X         4.693e-6*cos(3*mas-5*map[2]+3.32665)+
  1852. X         4.571e-6*cos(2*mas-4*map[2]+4.27086)+
  1853. X         4.409e-6*cos(3*map[3]-map[2]-2.02158);
  1854. X}
  1855. X
  1856. X/* ....jupiter */
  1857. Xstatic
  1858. Xp_jupiter (t, s, dml, ds, dm, da)
  1859. Xdouble t, s;
  1860. Xdouble *dml, *ds, *dm, *da;
  1861. X{
  1862. X    double dp;
  1863. X    double x1, x2, x3, x4, x5, x6, x7;
  1864. X    double sx3, cx3, s2x3, c2x3;
  1865. X        double sx5, cx5, s2x5;
  1866. X    double sx6;
  1867. X        double sx7, cx7, s2x7, c2x7, s3x7, c3x7, s4x7, c4x7, c5x7;
  1868. X
  1869. X    aux_jsun (t, &x1, &x2, &x3, &x4, &x5, &x6);
  1870. X        x7 = x3-x2;
  1871. X    sx3 = sin(x3);
  1872. X    cx3 = cos(x3);
  1873. X        s2x3 = sin(2*x3);
  1874. X    c2x3 = cos(2*x3);
  1875. X        sx5 = sin(x5);
  1876. X    cx5 = cos(x5);
  1877. X        s2x5 = sin(2*x5);
  1878. X    sx6 = sin(x6);
  1879. X        sx7 = sin(x7);
  1880. X    cx7 = cos(x7);
  1881. X        s2x7 = sin(2*x7);
  1882. X    c2x7 = cos(2*x7);
  1883. X        s3x7 = sin(3*x7);
  1884. X    c3x7 = cos(3*x7);
  1885. X        s4x7 = sin(4*x7);
  1886. X    c4x7 = cos(4*x7);
  1887. X        c5x7 = cos(5*x7);
  1888. X
  1889. X    *dml = (3.31364e-1-(1.0281e-2+4.692e-3*x1)*x1)*sx5+
  1890. X          (3.228e-3-(6.4436e-2-2.075e-3*x1)*x1)*cx5-
  1891. X          (3.083e-3+(2.75e-4-4.89e-4*x1)*x1)*s2x5+
  1892. X          2.472e-3*sx6+1.3619e-2*sx7+1.8472e-2*s2x7+6.717e-3*s3x7+
  1893. X          2.775e-3*s4x7+6.417e-3*s2x7*sx3+
  1894. X          (7.275e-3-1.253e-3*x1)*sx7*sx3+
  1895. X          2.439e-3*s3x7*sx3-(3.5681e-2+1.208e-3*x1)*sx7*cx3;
  1896. X        *dml += -3.767e-3*c2x7*sx3-(3.3839e-2+1.125e-3*x1)*cx7*sx3-
  1897. X          4.261e-3*s2x7*cx3+
  1898. X          (1.161e-3*x1-6.333e-3)*cx7*cx3+
  1899. X          2.178e-3*cx3-6.675e-3*c2x7*cx3-2.664e-3*c3x7*cx3-
  1900. X          2.572e-3*sx7*s2x3-3.567e-3*s2x7*s2x3+2.094e-3*cx7*c2x3+
  1901. X          3.342e-3*c2x7*c2x3;
  1902. X    *dml = degrad(*dml);
  1903. X
  1904. X    *ds = (3606+(130-43*x1)*x1)*sx5+(1289-580*x1)*cx5-6764*sx7*sx3-
  1905. X         1110*s2x7*sx3-224*s3x7*sx3-204*sx3+(1284+116*x1)*cx7*sx3+
  1906. X         188*c2x7*sx3+(1460+130*x1)*sx7*cx3+224*s2x7*cx3-817*cx3+
  1907. X         6074*cx3*cx7+992*c2x7*cx3+
  1908. X         508*c3x7*cx3+230*c4x7*cx3+108*c5x7*cx3;
  1909. X    *ds += -(956+73*x1)*sx7*s2x3+448*s2x7*s2x3+137*s3x7*s2x3+
  1910. X         (108*x1-997)*cx7*s2x3+480*c2x7*s2x3+148*c3x7*s2x3+
  1911. X         (99*x1-956)*sx7*c2x3+490*s2x7*c2x3+
  1912. X         158*s3x7*c2x3+179*c2x3+(1024+75*x1)*cx7*c2x3-
  1913. X         437*c2x7*c2x3-132*c3x7*c2x3;
  1914. X    *ds *= 1e-7;
  1915. X
  1916. X    dp = (7.192e-3-3.147e-3*x1)*sx5-4.344e-3*sx3+
  1917. X         (x1*(1.97e-4*x1-6.75e-4)-2.0428e-2)*cx5+
  1918. X         3.4036e-2*cx7*sx3+(7.269e-3+6.72e-4*x1)*sx7*sx3+
  1919. X         5.614e-3*c2x7*sx3+2.964e-3*c3x7*sx3+3.7761e-2*sx7*cx3+
  1920. X         6.158e-3*s2x7*cx3-
  1921. X         6.603e-3*cx7*cx3-5.356e-3*sx7*s2x3+2.722e-3*s2x7*s2x3+
  1922. X         4.483e-3*cx7*s2x3-2.642e-3*c2x7*s2x3+4.403e-3*sx7*c2x3-
  1923. X         2.536e-3*s2x7*c2x3+5.547e-3*cx7*c2x3-2.689e-3*c2x7*c2x3;
  1924. X
  1925. X    *dm = *dml-(degrad(dp)/s);
  1926. X
  1927. X    *da = 205*cx7-263*cx5+693*c2x7+312*c3x7+147*c4x7+299*sx7*sx3+
  1928. X         181*c2x7*sx3+204*s2x7*cx3+111*s3x7*cx3-337*cx7*cx3-
  1929. X         111*c2x7*cx3;
  1930. X    *da *= 1e-6;
  1931. X}
  1932. X
  1933. X/* ....saturn */
  1934. Xstatic
  1935. Xp_saturn (t, s, dml, ds, dm, da, dhl)
  1936. Xdouble t, s;
  1937. Xdouble *dml, *ds, *dm, *da, *dhl;
  1938. X{
  1939. X    double dp;
  1940. X    double x1, x2, x3, x4, x5, x6, x7, x8;
  1941. X    double sx3, cx3, s2x3, c2x3, s3x3, c3x3, s4x3, c4x3;
  1942. X        double sx5, cx5, s2x5, c2x5;
  1943. X    double sx6;
  1944. X        double sx7, cx7, s2x7, c2x7, s3x7, c3x7, s4x7, c4x7, c5x7, s5x7;
  1945. X    double s2x8, c2x8, s3x8, c3x8;
  1946. X
  1947. X    aux_jsun (t, &x1, &x2, &x3, &x4, &x5, &x6);
  1948. X        x7 = x3-x2;
  1949. X    sx3 = sin(x3);
  1950. X    cx3 = cos(x3);
  1951. X        s2x3 = sin(2*x3);
  1952. X    c2x3 = cos(2*x3);
  1953. X        sx5 = sin(x5);
  1954. X    cx5 = cos(x5);
  1955. X        s2x5 = sin(2*x5);
  1956. X    sx6 = sin(x6);
  1957. X        sx7 = sin(x7);
  1958. X    cx7 = cos(x7);
  1959. X        s2x7 = sin(2*x7);
  1960. X    c2x7 = cos(2*x7);
  1961. X        s3x7 = sin(3*x7);
  1962. X    c3x7 = cos(3*x7);
  1963. X        s4x7 = sin(4*x7);
  1964. X    c4x7 = cos(4*x7);
  1965. X        c5x7 = cos(5*x7);
  1966. X
  1967. X    s3x3 = sin(3*x3);
  1968. X    c3x3 = cos(3*x3);
  1969. X    s4x3 = sin(4*x3);
  1970. X    c4x3 = cos(4*x3);
  1971. X    c2x5 = cos(2*x5);
  1972. X    s5x7 = sin(5*x7);
  1973. X    x8 = x4-x3;
  1974. X    s2x8 = sin(2*x8);
  1975. X    c2x8 = cos(2*x8);
  1976. X    s3x8 = sin(3*x8);
  1977. X    c3x8 = cos(3*x8);
  1978. X
  1979. X    *dml = 7.581e-3*s2x5-7.986e-3*sx6-1.48811e-1*sx7-4.0786e-2*s2x7-
  1980. X          (8.14181e-1-(1.815e-2-1.6714e-2*x1)*x1)*sx5-
  1981. X          (1.0497e-2-(1.60906e-1-4.1e-3*x1)*x1)*cx5-1.5208e-2*s3x7-
  1982. X          6.339e-3*s4x7-6.244e-3*sx3-1.65e-2*s2x7*sx3+
  1983. X          (8.931e-3+2.728e-3*x1)*sx7*sx3-5.775e-3*s3x7*sx3+
  1984. X          (8.1344e-2+3.206e-3*x1)*cx7*sx3+1.5019e-2*c2x7*sx3;
  1985. X    *dml += (8.5581e-2+2.494e-3*x1)*sx7*cx3+1.4394e-2*c2x7*cx3+
  1986. X          (2.5328e-2-3.117e-3*x1)*cx7*cx3+
  1987. X          6.319e-3*c3x7*cx3+6.369e-3*sx7*s2x3+9.156e-3*s2x7*s2x3+
  1988. X          7.525e-3*s3x8*s2x3-5.236e-3*cx7*c2x3-7.736e-3*c2x7*c2x3-
  1989. X          7.528e-3*c3x8*c2x3;
  1990. X    *dml = degrad(*dml);
  1991. X
  1992. X    *ds = (-7927+(2548+91*x1)*x1)*sx5+(13381+(1226-253*x1)*x1)*cx5+
  1993. X         (248-121*x1)*s2x5-(305+91*x1)*c2x5+412*s2x7+12415*sx3+
  1994. X         (390-617*x1)*sx7*sx3+(165-204*x1)*s2x7*sx3+26599*cx7*sx3-
  1995. X         4687*c2x7*sx3-1870*c3x7*sx3-821*c4x7*sx3-
  1996. X         377*c5x7*sx3+497*c2x8*sx3+(163-611*x1)*cx3;
  1997. X    *ds += -12696*sx7*cx3-4200*s2x7*cx3-1503*s3x7*cx3-619*s4x7*cx3-
  1998. X         268*s5x7*cx3-(282+1306*x1)*cx7*cx3+(-86+230*x1)*c2x7*cx3+
  1999. X         461*s2x8*cx3-350*s2x3+(2211-286*x1)*sx7*s2x3-
  2000. X         2208*s2x7*s2x3-568*s3x7*s2x3-346*s4x7*s2x3-
  2001. X         (2780+222*x1)*cx7*s2x3+(2022+263*x1)*c2x7*s2x3+248*c3x7*s2x3+
  2002. X         242*s3x8*s2x3+467*c3x8*s2x3-490*c2x3-(2842+279*x1)*sx7*c2x3;
  2003. X    *ds += (128+226*x1)*s2x7*c2x3+224*s3x7*c2x3+
  2004. X         (-1594+282*x1)*cx7*c2x3+(2162-207*x1)*c2x7*c2x3+
  2005. X         561*c3x7*c2x3+343*c4x7*c2x3+469*s3x8*c2x3-242*c3x8*c2x3-
  2006. X         205*sx7*s3x3+262*s3x7*s3x3+208*cx7*c3x3-271*c3x7*c3x3-
  2007. X         382*c3x7*s4x3-376*s3x7*c4x3;
  2008. X    *ds *= 1e-7;
  2009. X
  2010. X    dp = (7.7108e-2+(7.186e-3-1.533e-3*x1)*x1)*sx5-7.075e-3*sx7+
  2011. X         (4.5803e-2-(1.4766e-2+5.36e-4*x1)*x1)*cx5-7.2586e-2*cx3-
  2012. X         7.5825e-2*sx7*sx3-2.4839e-2*s2x7*sx3-8.631e-3*s3x7*sx3-
  2013. X         1.50383e-1*cx7*cx3+2.6897e-2*c2x7*cx3+1.0053e-2*c3x7*cx3-
  2014. X         (1.3597e-2+1.719e-3*x1)*sx7*s2x3+1.1981e-2*s2x7*c2x3;
  2015. X    dp += -(7.742e-3-1.517e-3*x1)*cx7*s2x3+
  2016. X         (1.3586e-2-1.375e-3*x1)*c2x7*c2x3-
  2017. X         (1.3667e-2-1.239e-3*x1)*sx7*c2x3+
  2018. X         (1.4861e-2+1.136e-3*x1)*cx7*c2x3-
  2019. X         (1.3064e-2+1.628e-3*x1)*c2x7*c2x3;
  2020. X
  2021. X    *dm = *dml-(degrad(dp)/s);
  2022. X
  2023. X    *da = 572*sx5-1590*s2x7*cx3+2933*cx5-647*s3x7*cx3+33629*cx7-
  2024. X         344*s4x7*cx3-3081*c2x7+2885*cx7*cx3-1423*c3x7+
  2025. X         (2172+102*x1)*c2x7*cx3-671*c4x7+296*c3x7*cx3-320*c5x7-
  2026. X         267*s2x7*s2x3+1098*sx3-778*cx7*s2x3-2812*sx7*sx3;
  2027. X    *da += 495*c2x7*s2x3+688*s2x7*sx3+250*c3x7*s2x3-393*s3x7*sx3-
  2028. X         856*sx7*c2x3-228*s4x7*sx3+441*s2x7*c2x3+2138*cx7*sx3+
  2029. X         296*c2x7*c2x3-999*c2x7*sx3+211*c3x7*c2x3-642*c3x7*sx3-
  2030. X         427*sx7*s3x3-325*c4x7*sx3+398*s3x7*s3x3-890*cx3+
  2031. X         344*cx7*c3x3+2206*sx7*cx3-427*c3x7*c3x3;
  2032. X    *da *= 1e-6;
  2033. X
  2034. X    *dhl = 7.47e-4*cx7*sx3+1.069e-3*cx7*cx3+2.108e-3*s2x7*s2x3+
  2035. X          1.261e-3*c2x7*s2x3+1.236e-3*s2x7*c2x3-2.075e-3*c2x7*c2x3;
  2036. X    *dhl = degrad(*dhl);
  2037. X}
  2038. X
  2039. X/* ....uranus */
  2040. Xstatic
  2041. Xp_uranus (t, s, dl, dr, dml, ds, dm, da, dhl)
  2042. Xdouble t, s;
  2043. Xdouble *dl, *dr, *dml, *ds, *dm, *da, *dhl;
  2044. X{
  2045. X    double dp;
  2046. X    double x1, x2, x3, x4, x5, x6;
  2047. X    double x8, x9, x10, x11, x12;
  2048. X    double sx4, cx4, s2x4, c2x4;
  2049. X    double sx9, cx9, s2x9, c2x9;
  2050. X    double sx11, cx11;
  2051. X
  2052. X    aux_jsun (t, &x1, &x2, &x3, &x4, &x5, &x6);
  2053. X
  2054. X        x8 = mod2PI(1.46205+3.81337*t);
  2055. X        x9 = 2*x8-x4;
  2056. X    sx9 = sin(x9);
  2057. X    cx9 = cos(x9);
  2058. X        s2x9 = sin(2*x9);
  2059. X    c2x9 = cos(2*x9);
  2060. X
  2061. X    x10 = x4-x2;
  2062. X    x11 = x4-x3;
  2063. X    x12 = x8-x4;
  2064. X
  2065. X    *dml = (8.64319e-1-1.583e-3*x1)*sx9+(8.2222e-2-6.833e-3*x1)*cx9+
  2066. X          3.6017e-2*s2x9-3.019e-3*c2x9+8.122e-3*sin(x6);
  2067. X    *dml = degrad(*dml);
  2068. X
  2069. X    dp = 1.20303e-1*sx9+6.197e-3*s2x9+(1.9472e-2-9.47e-4*x1)*cx9;
  2070. X    *dm = *dml-(degrad(dp)/s);
  2071. X
  2072. X    *ds = (163*x1-3349)*sx9+20981*cx9+1311*c2x9;
  2073. X    *ds *= 1e-7;
  2074. X
  2075. X    *da = -3.825e-3*cx9;
  2076. X
  2077. X    *dl = (1.0122e-2-9.88e-4*x1)*sin(x4+x11)+
  2078. X         (-3.8581e-2+(2.031e-3-1.91e-3*x1)*x1)*cos(x4+x11)+
  2079. X         (3.4964e-2-(1.038e-3-8.68e-4*x1)*x1)*cos(2*x4+x11)+
  2080. X         5.594e-3*sin(x4+3*x12)-1.4808e-2*sin(x10)-
  2081. X         5.794e-3*sin(x11)+2.347e-3*cos(x11)+9.872e-3*sin(x12)+
  2082. X         8.803e-3*sin(2*x12)-4.308e-3*sin(3*x12);
  2083. X
  2084. X    sx11 = sin(x11);
  2085. X    cx11 = cos(x11);
  2086. X    sx4 = sin(x4);
  2087. X    cx4 = cos(x4);
  2088. X    s2x4 = sin(2*x4);
  2089. X    c2x4 = cos(2*x4);
  2090. X    *dhl = (4.58e-4*sx11-6.42e-4*cx11-5.17e-4*cos(4*x12))*sx4-
  2091. X          (3.47e-4*sx11+8.53e-4*cx11+5.17e-4*sin(4*x11))*cx4+
  2092. X          4.03e-4*(cos(2*x12)*s2x4+sin(2*x12)*c2x4);
  2093. X    *dhl = degrad(*dhl);
  2094. X
  2095. X    *dr = -25948+4985*cos(x10)-1230*cx4+3354*cos(x11)+904*cos(2*x12)+
  2096. X         894*(cos(x12)-cos(3*x12))+(5795*cx4-1165*sx4+1388*c2x4)*sx11+
  2097. X         (1351*cx4+5702*sx4+1388*s2x4)*cos(x11);
  2098. X    *dr *= 1e-6;
  2099. X}
  2100. X
  2101. X/* ....neptune */
  2102. Xstatic
  2103. Xp_neptune (t, s, dl, dr, dml, ds, dm, da, dhl)
  2104. Xdouble t, s;
  2105. Xdouble *dl, *dr, *dml, *ds, *dm, *da, *dhl;
  2106. X{
  2107. X    double dp;
  2108. X    double x1, x2, x3, x4, x5, x6;
  2109. X    double x8, x9, x10, x11, x12;
  2110. X    double sx8, cx8;
  2111. X    double sx9, cx9, s2x9, c2x9;
  2112. X    double s2x12, c2x12;
  2113. X
  2114. X    aux_jsun (t, &x1, &x2, &x3, &x4, &x5, &x6);
  2115. X
  2116. X        x8 = mod2PI(1.46205+3.81337*t);
  2117. X        x9 = 2*x8-x4;
  2118. X    sx9 = sin(x9);
  2119. X    cx9 = cos(x9);
  2120. X        s2x9 = sin(2*x9);
  2121. X    c2x9 = cos(2*x9);
  2122. X
  2123. X    x10 = x8-x2;
  2124. X    x11 = x8-x3;
  2125. X    x12 = x8-x4;
  2126. X
  2127. X    *dml = (1.089e-3*x1-5.89833e-1)*sx9+(4.658e-3*x1-5.6094e-2)*cx9-
  2128. X          2.4286e-2*s2x9;
  2129. X    *dml = degrad(*dml);
  2130. X
  2131. X    dp = 2.4039e-2*sx9-2.5303e-2*cx9+6.206e-3*s2x9-5.992e-3*c2x9;
  2132. X
  2133. X    *dm = *dml-(degrad(dp)/s);
  2134. X
  2135. X    *ds = 4389*sx9+1129*s2x9+4262*cx9+1089*c2x9;
  2136. X    *ds *= 1e-7;
  2137. X
  2138. X    *da = 8189*cx9-817*sx9+781*c2x9;
  2139. X    *da *= 1e-6;
  2140. X
  2141. X    s2x12 = sin(2*x12);
  2142. X    c2x12 = cos(2*x12);
  2143. X    sx8 = sin(x8);
  2144. X    cx8 = cos(x8);
  2145. X    *dl = -9.556e-3*sin(x10)-5.178e-3*sin(x11)+2.572e-3*s2x12-
  2146. X         2.972e-3*c2x12*sx8-2.833e-3*s2x12*cx8;
  2147. X
  2148. X    *dhl = 3.36e-4*c2x12*sx8+3.64e-4*s2x12*cx8;
  2149. X    *dhl = degrad(*dhl);
  2150. X
  2151. X    *dr = -40596+4992*cos(x10)+2744*cos(x11)+2044*cos(x12)+1051*c2x12;
  2152. X    *dr *= 1e-6;
  2153. X}
  2154. X
  2155. EOFxEOF
  2156. len=`wc -c < plans.c`
  2157. if expr $len != 17648 > /dev/null
  2158. then echo Length of plans.c is $len but it should be 17648.
  2159. fi
  2160.  
  2161.